1. Introduction
The opportunity is that the company changes a new set of interfaces and requires full packet encryption. In the past, symmetric encryption modes 3DES and AES were basically used in the company’s projects. Because there is only one pair of symmetric encryption keys, there is a great risk of key leakage. In this extremely sensitive industry of finance, the requirements for safety are also extremely high. Take advantage of this opportunity to uniformly replace the encryption modes in your project with RSA asymmetric encryption.
2. Encryption algorithm
This article will not explain the principle of RSA encryption algorithm in detail. In today’s Internet era, detailed information about RSA algorithms is easily available. The security field is also a field that can be dug deeply. This article focuses on engineering and only gives a simple explanation of some basic concepts.
- Symmetric and asymmetric encryption
1. Symmetric encryption: encryption and decryption use the same set of keys. The defect is that there are risks in key management. Common encryption modes include DES, 3DES, and AES.
Asymmetric encryption: encryption and decryption using different keys, public key encryption private key decryption. Common encryption modes are RSA.
- RSA common usage:
1. Encrypt public keys and decrypt private keys;
2. Sign the private key.
3. Check the public key.
Practice 3.
1. Generate key:
Use the terminal openssl command to generate the key
1). Generate a private key with a length of 2048 bits and base64 encoding.
openssl genrsa -out rsa_private_key.pem 2048
Copy the code
There are some special instructions about the key length. Each encrypted data cannot exceed the length of the key. If the key is 2048 bits long, only 245 bytes of data can be encrypted at a time. (That 11 bytes is the RSA reserved length). If the length of the data to be encrypted exceeds 245 bytes, the data needs to be segmented.
2). Generate a public key from the previously generated private key:
openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout
Copy the code
3). Convert the public key toPKCS8
Format, which can be used directly in iOS projects:
openssl pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt
Copy the code
In the case of our company, the private key and public key are generated by the company background, and the public key in. Pem format is provided to the mobile terminal, so I directly use the public key in PKCS8 format.
Note: It is not recommended to save the private key in the client, the consequences of private key leakage will be very serious!
2. Used in the project:
The Demo address: github.com/OhSuperRui/…
The above is the RSA tool class THAT I use, which supports various daily uses of RSA in mobile terminal: encryption, decryption, signing, checking. Different from many online tools, you do not need to import key files in p12 or DER format. It is very convenient to support key files in string format. And it uses Apple’s own Security. Framework. Many of the routines on the web are using openSSL that set of encryption tools class, implementation is also very convenient but the package size is a little bit large.
If using an IDE of Xcode8 and above, set KeyChain sharing to YES in Capabilities
1.) Public key encryption
NSString *string = @"doRSAEncrypt";
NSString *publickey = @"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA61sODmFj/OXnrHUYzams\ c/6XLni9G0HYv9sBewaPjF6qlu845nwmYSA6dQ9zPk231o5l3tmHLpUQGNnp/5rH\ +84iB/tM+Y+2kTI8uILGbmby2DL3rgzBG+I9h7e3w3QktpdcD8Z+ZuEVa/CY3Xez\ 8X1uknEVzIIhDKY7ipAoebchVdELbTlH1BRLz8RH6mQ+Z8REH4UL0TiQLfSfTotv\ 1G5ZerNxVZ7Toi4K9KFDA+1UD+LeDGg8PY/sdg0AJpR4o6bfDBko50wKLDz4UYyp\ 7EFZv661o2Mr7+KoQ6Tpb7w8bTl7wrRKz9ugB5+tM2F7aDvv1mzr7STIF+2c7tEx\ DQIDAQAB";
NSString *encryptString = [IPNRSAUtil encryptString:string publicKey:publickey];
Copy the code
2.) Private key decryption
NSString *privatekey = @"MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDrWw4OYWP85ees\
dRjNqaxz/pcueL0bQdi/2wF7Bo+MXqqW7zjmfCZhIDp1D3M+TbfWjmXe2YculRAY\
2en/msf7ziIH+0z5j7aRMjy4gsZuZvLYMveuDMEb4j2Ht7fDdCS2l1wPxn5m4RVr\
8Jjdd7PxfW6ScRXMgiEMpjuKkCh5tyFV0QttOUfUFEvPxEfqZD5nxEQfhQvROJAt\
9J9Oi2/Ubll6s3FVntOiLgr0oUMD7VQP4t4MaDw9j+x2DQAmlHijpt8MGSjnTAos\
PPhRjKnsQVm/rrWjYyvv4qhDpOlvvDxtOXvCtErP26AHn60zYXtoO+/WbOvtJMgX\
7Zzu0TENAgMBAAECggEBAOMf6w+ror9y6sE9+6K1hEwoO6NIN06vm8mCQwqDiVIw\
JTYlQ+cBllQSsvc24sMUYz32C48ko1Ur2u3wleXqa+Wvxp2nQWBw9QFn1rtE0NPI\
G8DSZr0bZ9xN1406mWdQlQF0Tg6XQnJr8q1I8WyAUTHSFzvRT/Uc+2Hmpf0RI05Y\
t0dt5bsGn/g+ijGbCm63Z2U8u5yWXidxWfU/KyYf1Y3mw9lGLR6IJc/q9N+TO4ih\
JM5pCraMFI4zWblGobkN2WKy7MrQ45FLSKul4W00+VyM/rVivW/fYUaqFEnlBog3\
/4hgI6Bsw2IuSk2Ubhbc4fp//146vJf6oL4WAJHmAiECgYEA+e3AFph8joC5gC1Q\
ok97tLJqt95fZCx4VCw6lPPbWxOHG6TJlvlo7kZIeUfKrGIlOWn38yuw5thEZKwW\
bzE8kn5WGlUgkOQ7hJ6Iiw/TzCFPRHxV63WBKa8OnyFIn3w91zI8ZTcUgrgyns+F\
gE5uxkEjb6iIyxxnpqC7Fk3lnikCgYEA8RKtn7kqoe0T/Yv7UsPLm7KzuWn3/01r\
LGA+x+GCp4rP2Lf0u1K+7VY6Dv/ceTBuA/2Yujenkjt0LaF+Bz0tLWFB5BTw3n+u\
6QshVdP3O1im4w6p3e8O9mfBCSV/CX5oBkbamemyQ7DTB9VtYNNmtGTs2aySuoel\
zPU0czETEEUCgYAjVhwclb62nzibCM0nxbkl2TwBdy1hinAQ5pf5y2iuPdqSbAAc\
mnLdjY5dp2reaJn+vh7SgNDoMpeo7DPX0MxRog8mdfa+xaYsoAWKM9isOeFtO28i\
dWCnthqJITmVYwmTTYUAgoMh4E036vtjIrPC0B7kgJ2mqgN1qbAJ/UWD0QKBgFSO\
U53hacWwDUHydm2aRXFQJd/T/mtq8Tt4aqzbOWOgubRvGYUWyecfRm/6aI+NYBlA\
OvCeEsWk2uQib70ERTNUmLLycWXpbSVKhR/AoEgNmUOs4gH5FstwqvGVWFCxKLWC\
5qvzn1ZE0FBAGQRMQgrmF3lmIXURnSMdoo8A2IntAoGAVCFmPpXvI8rMk2N3CvQ4\
dkDfP3W6w1KpyMzuQRZE9N1IUBYh3KN25HfzeW1OIFHPuxInMm/6zaU/rUHJSy/b\
ynVdQ6jvM4ZIt3rYUXZN6+a14AeA/MNNrY2LzCYlCxWIbVyNj9UN8/uda0zEtZ73\
RWYX1BlKVMSIx5Bf7eNH4fI=";
NSString *decryptString = [IPNRSAUtil decryptString:encryptString privateKey:privatekey];
Copy the code
3.) Private key signing
NSString *signature = [IPNRSAUtil rsaSignString:string WithPrivateKey:privatekey];
Copy the code
4.) Public key check
BOOL result = [IPNRSAUtil rsaVerifySignature:signature plainString:string WithPublicKey:publickey];
Copy the code
5.) Fragment encryption
If the length of the data to be encrypted is greater than the length of the key, the encrypted data needs to be segmented
// n indicates the single encryption length of the key. The key of 2048 bits is used here. Therefore, the value of n is 245(2048/8-11).
NSInteger n = 245;
NSMutableData *preData = [[NSMutableData alloc] init];
for (NSInteger i=0; i<=ceilf(string.length / n); i++) {
NSString *subString = [string substringWithRange:NSMakeRange(i * n, MIN(n, string.length - i * 245))];
NSData *encryptData = [IPNRSAUtil encryptData:[subString dataUsingEncoding:NSUTF8StringEncoding] publicKey:publickey];
// Segmented encryption needs to concatenate encrypted data. Do not convert data to string and concatenate data, which will cause errors.
[preData appendData:encryptData];
}
NSData *finalData = [[NSData alloc] initWithData:preData];
finalData = [finalData base64EncodedDataWithOptions:0];
NSString *result = [[NSString alloc] initWithData:finalData encoding:NSUTF8StringEncoding];
Copy the code
4. Afterword.
It took me more than half a month to develop this tool class, read a lot of documents and routines, plus my own practice debugging to create this tool class. At the beginning of the use of openSSL that set of encryption tools to achieve, but feel that openSSL takes up a little space, or to use Security. Framework to achieve. Usually always busy with the implementation of business needs, ignoring the client side of the security, the online client security of this piece of resources are relatively limited, I hope this article can be helpful to the future.
5. Reference materials
I don’t have to list all the information I read, but I mainly get related resources through Google, GitHub, StackOverFlow, Jianshu, Zhihu and other platforms. Finally, a collective thank you to all contributors to the resource.