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 = ; i < [md5Dat length]; i++) {
[s appendFormat:@"%02x", hashValue[i]];
}
NSLog(@"%@",s);
4. RSA 密钥对生成
//RSA 生成密钥对
char seed[]={};
unsigned int keyLength = ;
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[]={};
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, ); 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, ); 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