preface

We are often asked in job interviews, how do you design a secure external interface? In fact, you can answer this point, add and check, this will make your interface more secure. Next, this article will learn to add and check signatures together with you. From theory to practice, refueling oh ~

  • Concepts related to cryptography
  • Add signature test signature concept
  • Why is it necessary to add and check the signature
  • Introduction to encryption Algorithms
  • Add validation API
  • Plus check code implementation
  • Public number: a boy picking up snails

This article has been included in the personal Github, if the article is useful, can give a star!

Github.com/whx123/Java…

Concepts related to cryptography

Plaintext, ciphertext, key, encryption, decryption

  • Plaintext: indicates information or data that is not encrypted.
  • Ciphertext: After the plaintext is encrypted by the encryption algorithm, it becomes ciphertext to ensure data security.
  • Key: a parameter that is entered in the algorithm that converts plaintext to ciphertext or ciphertext to plaintext. Keys are classified into symmetric keys and asymmetric keys.
  • Encryption: The process of converting plain text into ciphertext.
  • Decryption: The process of restoring ciphertext to plaintext.

Symmetric encryption, asymmetric encryption

  • Symmetric encryption: An encryption algorithm that uses the same key for encryption and decryption.

  • Asymmetric encryption: Asymmetric encryption algorithms require two keys (public and private). The public key and private key exist in a pair. If the public key is used to encrypt data, only the corresponding private key can be decrypted.


What is a public and private key?

  • The public key and private key are a pair of keys. If the public key is used to encrypt data, only the corresponding private key can be used to decrypt data.
  • Actually, the public key is the public secret key, the private key is the secret key that wants you to keep privately.
  • Asymmetric encryption algorithms require a pair of public and private keys

Suppose you have a file, you encrypt it with letter A, and only letter B can be decrypted; Or if you encrypt it with B, only A can decrypt it, then A and B are a pair of public and private keys. If key A is public, you should keep key B privately. In this case key A is the public key and key B is the private key. Conversely, if B is public, A needs to be kept, in which case the secret key B is the public key, and the secret key A is the private key.

Add signature test signature concept

  • The signature of the: Generates a digest of the original packet using the Hash function and encrypts the digest with the private key to obtain the digital signature of the packet.Note that the check-in process contains special private items, such as a personal private key.Usually, the requester will callDigital signature and original packetSend to the receiver.

  • Check: After receiving the original packet and the digital signature, the receiver uses the same Hash function to generate digest A from the packet. In addition, the public key provided by the other party is used to decrypt the digital signature to obtain the abstract B. By comparing whether A and B are the same, we can know whether the packet has been tampered.


This picture on the Internet is a little bit easier to understand:

Why is it necessary to add a signature for inspection

We already know the concepts of addition and verification in the previous section, so why are addition and verification required? Some friends may think that we should use “public key encryption, private key decryption”?

Now, let’s do a demo.

Let’s say we have company A, and we want to access company C’s money transfer system. In the beginning, company C sent its public key to Company A and kept the private key for itself. When A merchant from Company A initiates A transfer, Company A uses the public key of company C to encrypt the request packet. When the encrypted packet reaches company C’s transfer system, Company C uses its private key to uncover the packet. Suppose that in the process of transmission, the encrypted message is obtained by the middleman Actor, he is also depressed, because he has no private key, looking at the swan meat, but can not eat it. I wanted to modify the message and transfer one hundred million to my own account, haha. This implementation seems to be seamless and seamless.


However, if company C sends the public key to Company A in the first place and it is picked up by the middleman Actor, there is A problem.

The middleman Actor intercepts THE public key of C and sends his public key to COMPANY A, who mistakenly thinks it is the public key of company C. A during A transfer, with the Actor’s public key, the request message encryption, the encryption message to in transit, the Actor interception again, at that time, he used his private key to decrypt, and then modify the message (to turn A billion), then use C public-key encryption, to C company, company C after receiving the message, continue to use their own private key to decrypt. Finally, is the transfer account of company A lost 100 million ~


How does company C tell whether the packet is from A or modified by an intermediary? In order to indicate the identity and authenticity of the message, it is necessary to “add the signature check”!

Company A also sends its public key to company C and keeps the private key. When initiating a transfer, the request message is signed with its own private key and its own digital signature is obtained. The digital signature and the request packet are sent to company C. After receiving the packet, company C checks the public key of A. If the original packet is inconsistent with the summary of the digital signature, the packet is tampered with


Some friends may have questions, assuming that when A sends its own public key to COMPANY C, it is also intercepted by the Actor in the middle. Let’s simulate a wave of actors that intercept public keys and see what happens

Assume that the Actor intercepts the public key of A and then intercepts the packet sent from A to C. When he intercepts a message, the first thing he wants to do is change the message. However, it is not possible to modify the original message only, because it will surely fail the verification after being sent to C Company. However, it seems that digital signatures cannot be solved because message digest algorithms cannot be solved backwards, only for verification….

So, public and private keys are used for encryption and encryption, “add and check is used to prove the identity”, so as not to be tampered with.

Introduction to common encryption algorithms

  • Message digest algorithm
  • Symmetric encryption algorithm
  • Asymmetric encryption algorithm
  • The secret algorithm

Message digest algorithm:

  • The same plaintext data through the same message digest algorithm will get the same ciphertext result value.
  • The data is processed by message summarization algorithm, and the summary result value can not be restored to the data before processing.
  • Data summarization algorithms are also known as Hash algorithms or hashing algorithms.
  • Message digest algorithm is generally used for signature verification.

Message Digest algorithms are divided into three types: Message Digest (MD), Secure Hash Algorithm (SHA), and Message Authentication Code (MAC).


MD family algorithm

MD (Message Digest) family, including MD2, MD4, MD5.

  • The result of MD2, MD4, and MD5 calculations is a 128-bit (16-byte) hash value, which is used to ensure complete and consistent information transmission.
  • MD2 has a slower but relatively secure algorithm, MD4 is fast but less secure, and MD5 is safer and faster than MD4.
  • MD5 is widely used in data integrity check, data (message) digest, data encryption, etc.
  • MD5 can be hacked. For data requiring high security, experts generally recommend switching to other algorithms, such as SHA-2. In 2004, MD5 was proved to be unable to prevent collision attacks and therefore not suitable for security authentication such as SSL public key authentication or digital signatures.

As an example, let’s see how to get the MD5 value of a string:

public class MD5Test {

    public static void main(String[] args) throws UnsupportedEncodingException {
        String s = "123";
        byte[] result = getMD5Bytes(s.getBytes());
 StringBuilder stringBuilder = new StringBuilder();  for (byte temp : result) {  if (temp >= 0 && temp < 16) {  stringBuilder.append("0");  }  stringBuilder.append(Integer.toHexString(temp & 0xff));  }  System.out.println(s + ", after MD5 encryption: + stringBuilder.toString());  }   private static byte[] getMD5Bytes(byte[] content) {  try {  MessageDigest md5 = MessageDigest.getInstance("MD5");  return md5.digest(content);  } catch (NoSuchAlgorithmException e) {  throw new RuntimeException(e);  }  } }   Copy the code

Running results:

After 123, MD5 encryption: 202 cb962ac59075b964b07152d234b70Copy the code

ShA family algorithm

Secure Hash Algorithm (SHA), including SHA-0, SHA-1,SHA-2 (SHA-256,SHA-512,SHA-224,SHA-384), and SHA-3. It is implemented on the basis of MD algorithm, and the difference between MD algorithm and SHA algorithm is that the digest length is longer and the security is higher.

  • Sha-0, the predecessor of SHA-1, was quickly withdrawn by the N.S.A. because it contained errors that made passwords less secure.
  • Sha-1 is widely used in many security protocols, including TLS, GnuPG, SSH, S/MIME, and IPsec, and is the successor to MD5.
  • Sha-2 includes SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, and SHA-512/256. Its algorithm is basically similar to SHA-1, with no obvious weaknesses so far.
  • Sha-3 was released in 2015 and was born out of a “successful hack of MD5” and a theoretical hack of SHA-0 and SHA-1. It differs from previous algorithms in that it is a replaceable cryptographic hashing algorithm.

Sha-1,SHA-2 (SHA-256,SHA-512,SHA-224,SHA-384), sha-1,SHA-2 (SHA-256,SHA-512,SHA-224,SHA-384), sha-1,SHA-2 (SHA-256,SHA-512,SHA-224,SHA-384

Algorithm type Abstract Length (bits) Maximum input message length (bits) Collision attack (bits) Performance Example (MiB/ S)
MD5 128 infinite ≤18 (Collision detected) 335
SHA-1 160 2^64 − 1 <63 (collision found) 192
SHA-224 224 2^64 − 1 112 139
SHA-256 256 2^64 − 1 128 139
SHA-384 384 2^128 − 1 192 154
SHA-512 512 2^128 − 1 256 154

MAC algorithm family

MAC algorithm Message Authentication Code (MAC) is a Hash function with a key. Input key and message, output a message digest. It combines MD and SHA message digest algorithms.

  • MD algorithms: HmacMD2, HmacMD4 and HmacMD5;
  • SHA algorithms include HmacSHA1, HmacSHA224, HmacSHA256, HmacSHA384, and HmacSHA512.

Symmetric encryption algorithm

An encryption algorithm that uses the “same key” for encryption and decryption is a symmetric encryption algorithm. Common symmetric encryption algorithms include AES, 3DES, DES, RC5, and RC6.


DES

Data Encryption Standard (DES) is a symmetric key Encryption block cipher algorithm. The DES algorithm has three entry parameters: Key, Data, and Mode.

  • Key: contains 7 bytes and 56 bits. It is the working Key of the DES algorithm.
  • Data: 8 bytes of 64-bit Data to be encrypted or decrypted.
  • Mode: encryption or decryption.

3DES

Triple Data Encryption Algorithm (also known as Triple DES (3DES)) is a symmetric key Encryption block cipher. It is equivalent to applying the DES Algorithm three times to each Data block.

AES

AES (Advanced Encryption Standard), also known as Rijndael in cryptography, is a block Encryption Standard adopted by the FEDERAL government of the United States.

  • Symmetric block cipher system is adopted, the key length is 128 bits, 192 bits, 256 bits, and the block length is 128 bits
  • Compared with DES, AES has better security, efficiency, and flexibility.

Asymmetric encryption algorithm

Asymmetric encryption algorithms require two keys: public and private. The public key and private key are paired. If the public key is used to encrypt data, only the corresponding private key can be used to decrypt data. The main asymmetric encryption algorithms are RSA, Elgamal, DSA, D-H, and ECC.


RSA algorithm

  • RSA is an asymmetric encryption algorithm widely used in encryption and digital signature
  • Principle of RSA algorithm: The product of two large prime numbers is extremely difficult to factor, so the product can be exposed as an encryption key.
  • RSA is the most widely studied public key algorithm. It has been tested by various attacks since it was proposed. It is generally regarded as one of the best public key schemes at present.

DSA

  • Digital Signature Algorithm (DSA) is also an asymmetric encryption Algorithm.
  • The difference between DSA and RSA is that DSA is only used for digital signature and cannot be used for data encryption and decryption. Its security is similar to RSA, but its performance is better.

ECC algorithm

  • ECC (Elliptic Curve Cryptography), based on Elliptic curve encryption.
  • The main advantage of Ecc is that, in some cases, it uses smaller keys than other methods, such as the RSA encryption algorithm, providing an equivalent or higher level of security.
  • One disadvantage is that the encryption and decryption operations take longer to implement than other mechanisms (which are CPU intensive compared to RSA).

The secret algorithm

National cryptography is the domestic cryptography algorithm identified by the State Cryptography Administration. In order to ensure the security of commercial passwords, the State Commercial Password Management Office has formulated a series of password standards, namely, SM1, SM2, SM3, SM4 and other national encryption algorithms.


SM1

  • SM1 is a symmetric encryption algorithm with 128-bit encryption strength, based on hardware implementation.
  • SM1 has the same encryption strength and performance as AES.

SM2

  • SM2 consists of three parts: signature algorithm, key exchange algorithm, and encryption algorithm
  • SM2 replaces the RSA encryption algorithm. It is based on ECC and has low efficiency.

SM3

  • SM3 is a home-made message summarization algorithm.
  • It is suitable for digital signature and authentication, message authentication code generation and authentication, and random number generation in commercial cryptography applications.

SM4

  • SM4 is a grouping algorithm for wireless LAN products.
  • The algorithm has a packet length of 128 bits and a key length of 128 bits.
  • Both encryption algorithm and key extension algorithm adopt 32 – round nonlinear iteration structure.
  • The structure of the decryption algorithm is the same as that of the encryption algorithm, but the order of use of the round key is reversed.
  • Its function is similar to DES of the International algorithm.

Check the related Java API

This section introduces the API used to add checkers


Sign related API

- java.security.Signature.getInstance(String algorithm); // Initializes the signature object according to the corresponding algorithm- KeyFactory.getInstance(String algorithm); // Generate the KeyFactory object according to the corresponding algorithm- KeyFactory.generatePrivate(KeySpec keySpec); // Generate private key- Java. Security. Signature. InitSign (PrivateKey PrivateKey) / / by private key, initialize the Signature of the object- Java. Security. Signature. Update (byte [] data) / / update the original message to the Signature of the object- java.security.Signature.sign(); / / the signatureCopy the code

Signature.getInstance(String algorithm);

  • Initializes the signature object based on the corresponding algorithm
  • The algorithm parameter can be SHA256WithRSA or MD5WithRSA. SHA256WithRSA indicates that SHA256 algorithm is used to generate the abstract and RSA algorithm is used to sign the signature

KeyFactory.getInstance(String algorithm);

  • Generate the KeyFactory object according to the corresponding algorithm, such as your public and private key using RSA algorithm, then pass RSA

KeyFactory.generatePrivate(KeySpec keySpec)

  • Generate private key, checkmark using private key ha, so you need to use KeyFactory to construct a private key object.

Signature.initSign(PrivateKey privateKey)

  • The checker uses a private key, so pass in the private key and initialize the checker object

Signature.update(byte[] data)

  • Updates the original message to the signed object

java.security.Signature.sign();

  • The sign operation is performed

Check relevant API

- java.security.Signature.getInstance(String algorithm); // Initializes the signature object according to the corresponding algorithm- KeyFactory.getInstance(String algorithm); // Generate the KeyFactory object according to the corresponding algorithm- KeyFactory.generatePublic(KeySpec keySpec); // Generate a public key- java.security.Signature.initVerify(publicKey); // From the public key, the initial test TAB object- Java. Security. Signature. Update (byte [] data) / / update the original message to the test object- java.security.Signature.verify(byte[] signature); / / attestationCopy the code

Signature.getInstance(String algorithm)

  • Initializes the signature object according to the corresponding algorithm. Note that check and add must use the same algorithm parameter

KeyFactory.getInstance(String algorithm);

  • The KeyFactory object is generated according to the corresponding algorithm

KeyFactory.generatePublic(KeySpec keySpec);

  • Generate a public key, check the use of the public key, through the KeyFactory to construct a public key object

**Signature.initVerify(publicKey); **

  • Public key check, so the public key object parameters, the initial test sign object

Signature.update(byte[] data)

  • Updates the original message to the signed object

Signature.verify(byte[] signature);

  • Conduct inspection

Plus check code implementation

After discussing the concepts in the previous sections, it is time to practice the code. Here I use SHA-256 as the digest algorithm and RSA as the signature verification algorithm, as follows:

package pattern;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.*; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec;  / * ** Add signature check demo* @author A little boy picking up field snails* /public class SignatureTest { // Public key Character string private static final String PUBLIC_KEY_STR = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDaJzVjC5K6kbS2YE2fiDs6H8pB\n" +  "JFDGEYqqJJC9I3E0Ebr5FsofdImV5eWdBSeADwcR9ppNbpORdZmcX6SipogKx9PX\n" +  "5aAO4GPesroVeOs91xrLEGt/arteW8iSD+ZaGDUVV3+wcEdci/eCvFlc5PUuZJou\n" +  "M2XZaDK4Fg2IRTfDXQIDAQAB"; // Private key Character string private static final String PRIVATE_KEY_STR = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBANonNWMLkrqRtLZg\n" +  "TZ+IOzofykEkUMYRiqokkL0jcTQRuvkWyh90iZXl5Z0FJ4APBxH2mk1uk5F1mZxf\n" +  "pKKmiArH09floA7gY96yuhV46z3XGssQa39qu15byJIP5loYNRVXf7BwR1yL94K8\n" +  "WVzk9S5kmi4zZdloMrgWDYhFN8NdAgMBAAECgYA9bz1Bn0i68b2KfqRdgOfs/nbe\n" +  "0XNN1DLQp2t7WDfRCg01iI1zPkZgyFVZWtI85f5/uIrLs5ArLosL1oNuqqc0nNne\n" +  "CvJK+ZxvA98Hx3ZqYTzDnleR054YhofL5awbhSciYVic204DOG1rhSsYWMqtX7J7\n" +  "3geoWL7TYdMfYXcCAQJBAPMMKsz6ZJh98EeQ1tDG5gpAGWFQkYNrxZDelP/LjeO0\n" +  "TP3XkQnIpcaZoCs7V/rRGRGMWwQ2BUdc/01in89ZZ5ECQQDlx2oBc1CtOAm2UAhN\n" +  "1xWrPkZWENQ53wTrwXO4qbTGDfBKon0AehLlGCSqxQ71aufLkNO7ZlX0IHTAlnk1\n" +  "TvENAkAGSEQ69CXxgx/Y2beTwfBkR2/gghKg0QJUUkyLqBlMz3ZGAXJwTE1sqr/n\n" +  "HiuSAiGhwH0ByNuuEotO1sPGukrhAkAMK26a2w+nzPL+u+hkrwKPykGRZ1zGH+Cz\n" +  "19AYNKzFXJGgclCqiMydY5T1knBDYUEbj/UW1Mmyn1FvrciHoUG1AkAEMEIuDauz\n" +  "JabEAU08YmZw6OoDGsukRWaPfjOEiVhH88p00veM1R37nwhoDMGyEGXVeVzNPvk7\n" +  "cELg28MSRzCK";    public static void main(String[] args) throws SignatureException, NoSuchAlgorithmException, InvalidKeyException, IOException, InvalidKeySpecException { // Original message String plain = "Welcome to my official account, the little boy picking up snails."; / / the signature byte[] signatureByte = sign(plain);  System.out.println("The original message is :" + plain);  System.out.println("Signed result :");  System.out.println(new BASE64Encoder().encode(signatureByte)); / / attestation boolean verifyResult = verify(plain, signatureByte);  System.out.println("Inspection Result :" + verifyResult);  }  / * ** Sign method * @param plain  * @return  * @throws NoSuchAlgorithmException  * @throws InvalidKeyException  * @throws UnsupportedEncodingException  * @throws SignatureException * / private static byte[] sign(String plain) throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException, SignatureException { // Obtain the signature object instance according to the corresponding algorithm Signature signature = Signature.getInstance("SHA256WithRSA"); The private key is usually read in the configuration file. Here, for demonstration convenience, generate the private key object according to the private key string PrivateKey privateKey = getPriveteKey(PRIVATE_KEY_STR); // Initializes the signature object signature.initSign(privateKey); // Update the original message to the object signature.update(plain.getBytes("UTF-8")); / / the signature return signature.sign();  }  / * ** Verification method * @param plain  * @param signatureByte  * @return  * @throws NoSuchAlgorithmException  * @throws InvalidKeyException  * @throws IOException  * @throws SignatureException  * @throws InvalidKeySpecException * / private static boolean verify(String plain, byte[] signatureByte) throws NoSuchAlgorithmException, InvalidKeyException, IOException, SignatureException, InvalidKeySpecException { // Get the public key PublicKey publicKey = getPublicKey(PUBLIC_KEY_STR); // Obtain the signature object instance according to the corresponding algorithm Signature signature = Signature.getInstance("SHA256WithRSA"); // Initializes the signature object signature.initVerify(publicKey); // Update the original message to the signature object signature.update(plain.getBytes("UTF-8")); // Check the visa return signature.verify(signatureByte);  }   private static PublicKey getPublicKey(String publicKeyStr) throws InvalidKeySpecException, IOException {  PublicKey publicKey = null;  try {  java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec(  new BASE64Decoder().decodeBuffer(publicKeyStr)); RSA symmetric encryption algorithm java.security.KeyFactory keyFactory;  keyFactory = java.security.KeyFactory.getInstance("RSA"); // Generate a public key object publicKey = keyFactory.generatePublic(bobPubKeySpec);  } catch (NoSuchAlgorithmException e) {  e.printStackTrace();  }  return publicKey;  }   private static PrivateKey getPriveteKey(String privateKeyStr) {  PrivateKey privateKey = null;  PKCS8EncodedKeySpec priPKCS8;  try {  priPKCS8 = new PKCS8EncodedKeySpec(new BASE64Decoder().decodeBuffer(privateKeyStr));  KeyFactory keyf = KeyFactory.getInstance("RSA");  privateKey = keyf.generatePrivate(priPKCS8);  } catch (IOException | NoSuchAlgorithmException | InvalidKeySpecException e) {  e.printStackTrace();  }  return privateKey;  } } Copy the code

Running results:

The original message is: welcome to my public account, the little boy picking up snailsSigning result:Oz15/aybGe42eGHbc+iMoSYHSCc8tfRskTVjjGSTPD4HjadL0CC5JUWNUW0WxHjUb4MvxWo2oeWE
Qw0+m61d+JgBMto/TWcVDcgwL/AbObsbWdQ6E/fVRqG13clkE8MyKsjt9Z7tcbwpycYTv0rUR4co
rndAVfBdtv5KeV+OXqM=
Inspection result:true Copy the code

Reference and thanks

  • wikipedia
  • Baidu encyclopedia
  • Introduction to common message summarization algorithms
  • Talk about seven common encryption algorithms and their implementation
  • 【 Error-prone concept 】 State secret algorithm SM1 (SCB2), SM2, SM3, SM4, SM7, SM9, ZUC

Wechat official account