Pie-it takes you to crawl the RSA pitfall that have been crawled for years, iOS RAS encryption and communication problems with. NET, rsaios
Background
First of all, we are working on an APP recently, but our data interaction is in plain text =-=. This is what we can do, so we know how to encrypt it. However, encryption may also cause symmetric encryption, so you will be able to crack your application. Therefore, asymmetric encryption is used and each APP generates different RSA key pairs.
Initial Implementation
It is not difficult to implement RSA encryption on iOS, because there are openssl in iOS and the security. framework that comes with the system. I chose openSSL here because I am relatively lazy =-= I found someone else has already written it and used it directly. Security. framework is actually good, that is, I don't know how to use it.
Initial test of OpenSSL RSA
Demo address
This is written by someone on GitHub and implements RSA encryption for OpenSSL.
Problem
1. The private key generated by using OpenSSL on iOS is encoded in X509, while our server uses. NET (. NET encoding is PKCS #8) PS: (signature. Sorry, I don't know, right? The results of Baidu over the past few days are soy sauce,
. NET and JAVA (android) RSA communication can refer to this address. I personally sum up that JAVA supports different encoding formats in a centralized manner, so JAVA communication is not a problem
2. How to convert different certificates
Process
1. First found how to make the two generated ciphertext the same, but found that paddingPKCS1 such thing certainly does not work (declared failure)
2. Try to generate a key pair of PKCS #8 (I tried some openssl command lines, but the key pair was generated by the app in the end, so I failed to continue)
3. the. NET Server uses openssl to solve this problem (however, if so, android needs to be modified again, so it is declared to have abandoned)
4. Convert the key pair encoding (in fact, I have also looked for iOS and Java Communications, and I will not elaborate on them here)
This detour is actually quite long. I have summarized the following points, but it has been a day in history...
Let me talk about the last point. Some may ask me how I found the difference between the two key pairs.
Don't worry. We will continue after advertising.
Solve the problem
First, I suggest you download the code in github, which is easy to understand.
After you run the program once, you will find that the publicKey. pem and privateKey. pem files under your iPhone simulator directory
We need to hand over the publicKey to the server so that only my privateKey can be used for encryption. I will not explain these principles.
Then we open the publicKey.
/* This return value based on the key that generated by openssl. -----BEGIN RSA PUBLIC KEY----- MIGHAoGBAOp5TLclpWCaNDzHYPfB26SLmS8vlSXH4PyKopz5OS5Vx994FBQQLwv9 2pIJQsBk09egrL0gbASK1VCwDt0MmaiyrNFl/xaEzB/VOvjoojBUzMMIca9fKmx5 GAzSbSP7we64dhvrziuuNVTuM/e2XSa2skKFHMI0bCq4+pNYhvRhAgED -----END RSA PUBLIC KEY----- */
Then let's take a look at the source code
- (NSString*)publicKeyBase64{ NSFileManager *fm = [NSFileManager defaultManager]; if ([fm fileExistsAtPath:OpenSSLRSAPublicKeyFile]) { NSString *str = [NSString stringWithContentsOfFile:OpenSSLRSAPublicKeyFile encoding:NSUTF8StringEncoding error:nil]; NSData *data = [self publicKeyBitsWithString:[[str componentsSeparatedByString:@"-----"] objectAtIndex:2]]; return [data base64EncodedString]; } return nil;}
Here we can see that OpenSSL has changed the entire certificate file to Base64. That's right.
At first, I turned around and thought it was a key error. In fact, after the correct publicKey of OpenSSL is converted to NSData, the size must be 162. If you only use one of the two segments (no ---- ***** ----), it will be 140.
My colleague found a conversion process while checking the source code of OpenSSL. NET. Then I checked the code of. NET. The Code is as follows:
If you understand. net or. NET, you can understand very simple code.
So I have spared such a big bend, you should know it at first glance, and the next step is to handle it, so that the publicKey is changed to the 128-"PKCS #8 standard encoding, according. NET OpenSSL code Translation
If (unsigned long) [NSData dataWithBase64EncodedString: wrapper. publicKeyBase64]. length <162) {NSLog (@ "the public key format is incorrect! "); Return;} else {// fetch.. NET PubKey NSData * keyData = [NSData dataWithBase64EncodedString: wrapper. publicKeyBase64]; NSData * newKeyData = [keyData subdataWithRange: NSMakeRange (29,128)]; NSLog (@ "NewPubKey: % @", [newKeyData base64EncodedString]);}
Summary
The above is my processing process =-= This RSA pitfall is a real pitfall. If I didn't see the server code, I would not be able to solve it, because the local encryption and decryption are all OK, alas, this story tells us that we have to look at the problem from multiple aspects, and we can't just look at what we have on hand to look for information from multiple aspects. But this is because I will. NET, so I will think about it.
I hope this trap will help you.
This is a pitfall of some time ago. I found that I could not find any information on the Internet...
I am also using AES to view my personal blog. Of course, I will update it here ~