Hello, I'm brother dog. Recently, in connection with business parties, I need to give them an interface to call. This interface design involving external calls generally involves many aspects, such as:
- Signature is used to prevent data tampering
- Information encryption and key management
- Build oauth2 0 authentication authorization
- Use Token Mode
- Build a gateway to realize blacklist and whitelist
01 build API open platform in token mode
The following is the interface call flow chart of this scheme:
Scheme design:
- The third-party organization applies for an appId and obtains the accessToken through the appId. Each time it requests to obtain the accessToken, the old accessToken must be deleted
- The third-party organization needs to add the accessToken parameter to request data. Before the business processing center executes business each time, go to the dba persistence layer to check whether the accessToken exists (you can put the accessToken in redis, which has the effect of expiration time). The existence indicates that the organization is legal and can request business data without logging in. The absence indicates that this organization is illegal and does not return business data.
- Benefits: stateless design. Every request is guaranteed to be the request of the organization saved in our persistence layer. If someone steals our accessToken, they can re apply for a new token
02 based on oauth2 0 protocol mode
The principle of third-party authorization is the same as that of token 1:
- Suppose I am service provider a, I have a development interface, and external organization B must apply for its own appid (Organization B id) to request the interface of A
- When B wants to call the A interface to check A user's information, it needs the corresponding user authorization. Tell A that I am willing to agree to tell b my information, and A will produce an authorization token to B.
- B uses the token to obtain the information of a user.
Overall processing flow of joint wechat login:
- The user agrees to the authorization and obtains the code
- Exchange code for web access authorization_ token
- Through access_ Get user openId with token
- Get user information through openId
03 information encryption and key management
- One way hash encryption
- Symmetric encryption
- Asymmetric encryption
- Security key management
3.1 one way hash encryption
Hash is the extraction of information. Usually, its length is much smaller than that of information, and it is a fixed length. The hash with strong encryption must be irreversible, which means that no part of the original information can be deduced through the hash result. Any change in input information, even if only one bit, will lead to significant changes in hash results, which is called avalanche effect. Hashing should also be conflict proof, that is, two pieces of information with the same hash result cannot be found. Hash results with these characteristics can be used to verify whether the information has been modified.
One way hash function is generally used to generate message digest, key encryption, etc. common are:
- MD5 (Message Digest Algorithm 5): it is a one-way hash algorithm developed by RSA data security company. It is non reversible. The same plaintext generates the same ciphertext.
- SHA (Secure Hash Algorithm): it can generate a 160 bit value for data of any length;
Comparison between SHA-1 and MD5
Because both are derived from MD4, SHA-1 and MD5 are very similar to each other. Accordingly, their strength and other characteristics are similar, but there are the following differences:
- Security against forced provisioning: the most significant and important difference is that the SHA-1 digest is 32 bits longer than the MD5 digest. Using the forced technology, the difficulty of generating any message so that its summary is equal to the given message summary is 2128 for MD5 and 2160 for SHA-1. In this way, SHA-1 has greater strength against forced attacks.
- Security of Cryptanalysis: due to the design of MD5, SHA-1 is vulnerable to cryptanalysis attacks.
- Speed: on the same hardware, SHA-1 runs slower than MD5.
- Features: avalanche effect, fixed length output and irreversible.
- The function is to ensure the integrity of data.
- Encryption algorithms: md5 (standard key length 128 bits), sha1 (standard key length 160 bits), md4, CRC-32
- Encryption tools: md5sum, sha1sum, OpenSSL, dgst.
- Calculate the hash value of a file, for example: md5sum / shalsum filename, OpenSSL, dgst – md5/-sha
3.2 symmetric encryption
Secret key: the same key is used for encryption and decryption, two-way guarantee of data confidentiality, high encryption efficiency, suitable for encrypting large data and large files, and low encryption strength (compared with asymmetric encryption)
Advantages and disadvantages of symmetric encryption
Advantages: compared with public key encryption, the operation speed is fast.
Disadvantages: it cannot be used as authentication, and it is difficult to issue keys
DES
It is a symmetric encryption algorithm. In the process of encryption and decryption, the key length must be a multiple of 8
public class DES { public DES() { } // test public static void main(String args[]) throws Exception { // Content to be encrypted String str = "123456"; // Password, if the length is a multiple of 8, the key can be set at will String password = "12345678"; byte[] encrypt = encrypt(str.getBytes(), password); System.out.println("Before encryption:" +str); System.out.println("After encryption:" + new String(encrypt)); // decrypt byte[] decrypt = decrypt(encrypt, password); System.out.println("After decryption:" + new String(decrypt)); } /** * encryption * * @param datasource * byte[] * @param password * String * @return byte[] */ public static byte[] encrypt(byte[] datasource, String password) { try { SecureRandom random = new SecureRandom(); DESKeySpec desKey = new DESKeySpec(password.getBytes()); // Create a key factory and use it to convert DESKeySpec to SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey securekey = keyFactory.generateSecret(desKey); // Cipher object actually completes the encryption operation Cipher cipher = Cipher.getInstance("DES"); // Initialize Cipher object with key, ENCRYPT_MODE is a constant used to initialize Cipher to encryption mode cipher.init(Cipher.ENCRYPT_MODE, securekey, random); // Now get the data and encrypt it // Formal encryption operation return cipher.doFinal(datasource); // Encrypt or decrypt data as a single part operation, or end a multi part operation } catch (Throwable e) { e.printStackTrace(); } return null; } /** * decrypt * * @param src * byte[] * @param password * String * @return byte[] * @throws Exception */ public static byte[] decrypt(byte[] src, String password) throws Exception { // DES algorithm requires a trusted random number source SecureRandom random = new SecureRandom(); // Create a DESKeySpec object DESKeySpec desKey = new DESKeySpec(password.getBytes()); // Create a key factory SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");// Returns the that implements the specified transformation // Cipher // object // Convert the DESKeySpec object to a SecretKey object SecretKey securekey = keyFactory.generateSecret(desKey); // The Cipher object actually completes the decryption operation Cipher cipher = Cipher.getInstance("DES"); // Initializing Cipher objects with keys cipher.init(Cipher.DECRYPT_MODE, securekey, random); // Really start decryption operation return cipher.doFinal(src); } } output Before encryption:123456 After encryption:>p.72| After decryption:123456
3.3 asymmetric encryption
Asymmetric encryption algorithm requires two keys: public key (public key for short) and private key (private key for short).
The public key and the private key are a pair
- The public key encrypts the data and can only be decrypted with the corresponding private key
- The private key encrypts the data and can only be decrypted with the corresponding public key
Process:
- Party A generates a pair of keys and discloses the public key. Party B encrypts the confidential information with Party A's public key and then sends it to Party A;
- Party A decrypts the encrypted information with its own private key.
- When Party A wants to reply to Party B, Party A shall use Party B's public key to encrypt the data
- Party B uses its own private key to decrypt.
Party A can only decrypt any information encrypted by its public key with its private key.
characteristic:
The algorithm strength is complex
Good confidentiality
The speed of encryption and decryption is not as fast as that of symmetric encryption and decryption.
In the symmetric cryptosystem, there is only one key and it is non-public. If you want to decrypt, you have to let the other party know the key. Therefore, to ensure its security is to ensure the security of the key, while the asymmetric key system has two kinds of keys, one of which is public, so there is no need to transmit the other party's key like a symmetric password. This makes it much safer
Applicable to: finance, payment field
RSA encryption is an asymmetric encryption
import javax.crypto.Cipher; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import org.apache.commons.codec.binary.Base64; /** * RSA Encryption and decryption tool class * * */ public class RSAUtil { public static String publicKey; // Public key public static String privateKey; // Private key /** * Generate public and private keys */ public static void generateKey() { // 1. Initialization key KeyPairGenerator keyPairGenerator; try { keyPairGenerator = KeyPairGenerator.getInstance("RSA"); SecureRandom sr = new SecureRandom(); // Random number generator keyPairGenerator.initialize(512, sr); // Set 512 bit long secret key KeyPair keyPair = keyPairGenerator.generateKeyPair(); // Start creating RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); // Transcoding publicKey = Base64.encodeBase64String(rsaPublicKey.getEncoded()); // Transcoding privateKey = Base64.encodeBase64String(rsaPrivateKey.getEncoded()); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * Private key encryption or decryption * * @param content * @param privateKeyStr * @return */ public static String encryptByprivateKey(String content, String privateKeyStr, int opmode) { // The private key should be processed with PKCS8 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyStr)); KeyFactory keyFactory; PrivateKey privateKey; Cipher cipher; byte[] result; String text = null; try { keyFactory = KeyFactory.getInstance("RSA"); // Restore Key object privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); cipher = Cipher.getInstance("RSA"); cipher.init(opmode, privateKey); if (opmode == Cipher.ENCRYPT_MODE) { // encryption result = cipher.doFinal(content.getBytes()); text = Base64.encodeBase64String(result); } else if (opmode == Cipher.DECRYPT_MODE) { // decrypt result = cipher.doFinal(Base64.decodeBase64(content)); text = new String(result, "UTF-8"); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return text; } /** * Public key encryption or decryption * * @param content * @param privateKeyStr * @return */ public static String encryptByPublicKey(String content, String publicKeyStr, int opmode) { // The public key should be processed with X509 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyStr)); KeyFactory keyFactory; PublicKey publicKey; Cipher cipher; byte[] result; String text = null; try { keyFactory = KeyFactory.getInstance("RSA"); // Restore Key object publicKey = keyFactory.generatePublic(x509EncodedKeySpec); cipher = Cipher.getInstance("RSA"); cipher.init(opmode, publicKey); if (opmode == Cipher.ENCRYPT_MODE) { // encryption result = cipher.doFinal(content.getBytes()); text = Base64.encodeBase64String(result); } else if (opmode == Cipher.DECRYPT_MODE) { // decrypt result = cipher.doFinal(Base64.decodeBase64(content)); text = new String(result, "UTF-8"); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return text; } // test method public static void main(String[] args) { /** * Note: private key encryption must be decrypted by public key encryption must be decrypted by private key * // During normal development, the back-end developer generates a good key pair, the server saves the private key, and the client saves the public key */ System.out.println("-------------Two pairs of secret keys are generated and kept by the sender and receiver respectively-------------"); RSAUtil.generateKey(); System.out.println("Public key:" + RSAUtil.publicKey); System.out.println("Private key:" + RSAUtil.privateKey); System.out.println("-------------Private key encryption public key decryption-------------"); String textsr = "11111111"; // Private key encryption String cipherText = RSAUtil.encryptByprivateKey(textsr, RSAUtil.privateKey, Cipher.ENCRYPT_MODE); System.out.println("After private key encryption:" + cipherText); // Public key decryption String text = RSAUtil.encryptByPublicKey(cipherText, RSAUtil.publicKey, Cipher.DECRYPT_MODE); System.out.println("After public key decryption:" + text); System.out.println("-------------Public key encryption private key decryption-------------"); // Public key encryption String textsr2 = "222222"; String cipherText2 = RSAUtil.encryptByPublicKey(textsr2, RSAUtil.publicKey, Cipher.ENCRYPT_MODE); System.out.println("After public key encryption:" + cipherText2); // Private key decryption String text2 = RSAUtil.encryptByprivateKey(cipherText2, RSAUtil.privateKey, Cipher.DECRYPT_MODE); System.out.print("After decryption of the private key:" + text2 ); } }
04 use signature to prevent data tampering
- Client: the requested data is divided into two parts (business parameters, signature parameters). Signature parameters = md5 (business parameters)
- Server: verify whether md5 (business parameter) is the same as the signature parameter
05 reference link
- blog.csdn.net/zhou920786312/article/details/95536556