Cryptopp 是一個c++寫的功能完善的密碼學工具,類似於openssl
官網:https://www.cryptopp.com
以下主要演示Cryptopp 在iOS上的RSA加密解密簽名與驗證簽名
1. 編譯cryptopp為iOS上使用的靜態庫
我整理好了一份 cryptopp5.6.2版本的打包腳本隨后在下面DEMO中一起發布,需要可自行下載
編譯其他版本的,簡單修改腳本就行
終端運行腳本
sh build-cryptopp.sh
就會生成如下目錄結構,
生成的靜態庫是通用版的,真機模擬器合並的,比較大200多M,實測打包之后幾百K,
打包之后libcryptopp.a 和 include 的頭文件,在ios上使用
2. 將上述打包的靜態庫以及 頭文件導入DEMO工程CryptoppDemo
將測試用的viewController.m 修改為 ViewController.mm
主要為了實現 oc ,c++的混編
3. 使用 md5
當然還支持其他hash算法

-(NSData*)getMD5Value:(NSData*)data { CryptoPP::MD5 md5; byte digest[ CryptoPP::MD5::DIGESTSIZE ]; md5.CalculateDigest(digest, (const byte*)[data bytes], [data length]); NSData * hashVale = [NSData dataWithBytes:digest length:sizeof digest]; return hashVale; } //MD5 NSString *testStr = @"hello world md5"; NSData *testDAT = [testStr dataUsingEncoding:NSUTF8StringEncoding]; NSData *md5Dat = [self getMD5Value:testDAT]; NSLog(@"%lu",md5Dat.length); NSMutableString *s = [NSMutableString string]; unsigned char * hashValue = (byte *)[md5Dat bytes]; int i; for (i = 0; i < [md5Dat length]; i++) { [s appendFormat:@"%02x", hashValue[i]]; } NSLog(@"%@",s);
4. RSA 密鑰對生成

//RSA 生成密鑰對 char seed[1024]={1}; unsigned int keyLength = 1024; char *privFilename = "/Users/cocoajin/Desktop/priKey.txt"; char *pubFilename = "/Users/cocoajin/Desktop/pubKey.txt"; CryptoPP::RandomPool randPool; randPool.IncorporateEntropy((byte *)seed, strlen(seed)); CryptoPP::RSAES_OAEP_SHA_Decryptor priv(randPool, keyLength); CryptoPP::HexEncoder privFile(new CryptoPP::FileSink(privFilename)); priv.DEREncode(privFile); privFile.MessageEnd(); CryptoPP::RSAES_OAEP_SHA_Encryptor pub(priv); CryptoPP::HexEncoder pubFile(new CryptoPP::FileSink(pubFilename)); pub.DEREncode(pubFile); pubFile.MessageEnd();
5. RSA 加密與解密

//RSA 加密 char seed[1024]={2}; char *pubFilename = "/Users/cocoajin/Desktop/pubKey.txt"; char *message = "hello ios cryptopp"; printf("%s\n",message); CryptoPP::FileSource pubFile(pubFilename, true, new CryptoPP::HexDecoder); CryptoPP::RSAES_OAEP_SHA_Encryptor pub(pubFile); CryptoPP::RandomPool randPool; randPool.IncorporateEntropy((byte *)seed, strlen(seed)); std::string encresult; CryptoPP::StringSource(message, true, new CryptoPP::PK_EncryptorFilter(randPool, pub, new CryptoPP::HexEncoder(new CryptoPP::StringSink(encresult)))); std::cout << encresult << std::endl; //RSA 解密 char *privFilename = "/Users/cocoajin/Desktop/priKey.txt"; CryptoPP::FileSource privFile(privFilename, true, new CryptoPP::HexDecoder); CryptoPP::RSAES_OAEP_SHA_Decryptor priv(privFile); CryptoPP::AutoSeededRandomPool _rng; CryptoPP::RSAES_OAEP_SHA_Decryptor tpriv(_rng, 1024); std::string decresult; CryptoPP::StringSource(encresult.c_str(), true, new CryptoPP::HexDecoder(new CryptoPP::PK_DecryptorFilter(_rng, priv, new CryptoPP::StringSink(decresult)))); std::cout << decresult << std::endl;
6. 簽名與驗證簽名

//RSA 簽名與較驗簽名 char *privFilename = "/Users/cocoajin/Desktop/priKey.txt"; char *pubFilename = "/Users/cocoajin/Desktop/pubKey.txt"; char *signatureFilename = "/Users/cocoajin/Desktop/sin.txt"; char *messageFileName = "/Users/cocoajin/Desktop/NOTES.txt"; CryptoPP::FileSource privFile(privFilename, true, new CryptoPP::HexDecoder); //GlobalRNG CryptoPP::AutoSeededRandomPool _rng; CryptoPP::RSAES_OAEP_SHA_Decryptor tpriv(_rng, 1024); CryptoPP::RSASSA_PKCS1v15_SHA_Signer priv(privFile); CryptoPP::FileSource f(messageFileName, true, new CryptoPP::SignerFilter(_rng, priv, new CryptoPP::HexEncoder(new CryptoPP::FileSink(signatureFilename)))); //驗證簽名 CryptoPP::FileSource pubFile(pubFilename, true, new CryptoPP::HexDecoder); CryptoPP::RSASSA_PKCS1v15_SHA_Verifier pub(pubFile); CryptoPP::FileSource signatureFile(signatureFilename, true, new CryptoPP::HexDecoder); if (signatureFile.MaxRetrievable() != pub.SignatureLength()) { printf("\nNO\n"); return; } CryptoPP::SecByteBlock signature(pub.SignatureLength()); signatureFile.Get(signature, signature.size()); CryptoPP::VerifierFilter *verifierFilter = new CryptoPP::VerifierFilter(pub); verifierFilter->Put(signature, pub.SignatureLength()); CryptoPP::FileSource ff(messageFileName, true, verifierFilter); printf("\n%d\n",verifierFilter->GetLastResult());
7. 其他相關cryptopp的用法可以參考:源碼test.cpp
8. CryptoppDemo下載
https://github.com/cocoajin/TDDDemo/tree/master/CryptoppDemo
參考:
https://github.com/3ign0n/CryptoPP-for-iOS
https://my.oschina.net/u/566591/blog/168520