基于Crypto++/Cryptopp的rsa密钥生成,rsa加密、解密,rsa签名、验签12

在项目中需要增加一个注册的功能,想到了用rsa非对称加密的方法。对比了openssl等第三方库,最后采用了Cryptopp。

1.源文件整理
可以在http://www.cryptopp.com/获取库的源文件,解压后将文件重新归档。头文件放置到include文件夹,cpp放到src目录。同时去除所有的test相关的cpp及非cpp、h文件。拷本cryptopp目录到工程目录下
2.加入工程
在vs2010工程中增加新的filter,命名为Cryptopp,再增加子filter include和src。将include下的h文件导入到include,将src下的cpp导入到src filter。
2014-06-27_171754
3.编译
打开src,选中所有的cpp文件,更改属性,将预编译头改为pch.h。将工程的vc++路径更新,增加include和src。
2014-06-27_171553
2014-06-27_171631
编译工程,如果编译不过修改一下错误。

4.生成rsa公钥、私钥,经过base64编码后保存到文件
需要导入一些头文件:

[cpp]  view plain  copy
  1. #include "iterhash.h"  
  2. #include "files.h"  
  3. #include "rsa.h"  
  4. #include "randpool.h"  
  5. #include "hex.h"  
  6. #include "base64.h"  
  7. #include "osrng.h"  


[cpp]  view plain  copy
  1. void CKeyController::GenerateRSAKey(unsigned int keyLength, CString decFilename, CString encFilename, CString seed)  
  2. {  
  3.     RandomPool randPool;  
  4.     randPool.Put((byte *)seed.GetBuffer(seed.GetLength()), seed.GetLength());  
  5.   
  6.     RSAES_OAEP_SHA_Decryptor decrypt(randPool, keyLength);  
  7.     HexEncoder decFile(new Base64Encoder(new FileSink(decFilename.GetBuffer(decFilename.GetLength()))));  
  8.   
  9.     decrypt.DEREncode(decFile);  
  10.     decFile.MessageEnd();  
  11.   
  12.     RSAES_OAEP_SHA_Encryptor encrypt(decrypt);  
  13.     HexEncoder encFile(new Base64Encoder(new FileSink(encFilename.GetBuffer(encFilename.GetLength()))));  
  14.     encrypt.DEREncode(encFile);  
  15.   
  16.     encFile.MessageEnd();  
  17.   
  18.     return;  
  19. }  
  20. RandomPool & CKeyController::GlobalRNG()  
  21. {  
  22.     static RandomPool randomPool;  
  23.     return randomPool;  
  24. }  

5.通过生成的公钥文件加密字符串

[cpp]  view plain  copy
  1. CString CKeyController::RSAEncryptString( CString encFilename, CString seed, CString message )  
  2. {  
  3.     string encString;  
  4.     FileSource encFile( encFilename.GetBuffer(encFilename.GetLength()), truenew Base64Decoder(new StringSink(encString)) );  
  5.     HexDecoder decoder;  
  6.     decoder.Put( (byte*)encString.c_str(), encString.size() );  
  7.     decoder.MessageEnd();  
  8.   
  9.     RSAES_OAEP_SHA_Encryptor enc;  
  10.     enc.AccessKey().Load(decoder);  
  11.   
  12.     RandomPool randPool;  
  13.     randPool.Put( (byte *)seed.GetBuffer(seed.GetLength()), seed.GetLength() );  
  14.   
  15.     string result;  
  16.     StringSource( c2s(message), truenew PK_EncryptorFilter(randPool, enc, new HexEncoder(new StringSink(result))) );  
  17.   
  18.     return CString(result.c_str());  
  19. }  

6.通过生成的私钥文件解密字符串

[cpp]  view plain  copy
  1. CString CKeyController::RSADecryptString( CString decFilename, CString ciphertext )  
  2. {  
  3.     string decString;  
  4.     FileSource decFile( decFilename.GetBuffer(decFilename.GetLength()), truenew Base64Decoder(new StringSink(decString)) );  
  5.     HexDecoder decoder;  
  6.     decoder.Put( (byte*)decString.c_str(), decString.size() );  
  7.     decoder.MessageEnd();  
  8.   
  9.     RSAES_OAEP_SHA_Decryptor dec;  
  10.     dec.AccessKey().Load(decoder);  
  11.   
  12.     string result;  
  13.     StringSource( c2s(ciphertext), truenew HexDecoder(new PK_DecryptorFilter(GlobalRNG(), dec, new StringSink(result))) );  
  14.   
  15.     return CString(result.c_str());  
  16. }  

7.使用私钥签名

[cpp]  view plain  copy
  1. CString CKeyController::SignMessage( const std::string& privateKeyFileName, const std::string& message )  
  2. {  
  3.     std::string signedMessage = "";  
  4.     string encString;  
  5.     FileSource privFile( privateKeyFileName.c_str(), truenew Base64Decoder(new StringSink(encString)));  
  6.     RSASSA_PKCS1v15_SHA_Signer priv;  
  7.   
  8.     HexDecoder decoder;  
  9.     decoder.Put( (byte*)encString.c_str(), encString.size() );  
  10.     decoder.MessageEnd();  
  11.   
  12.     priv.AccessKey().Load(decoder);  
  13.   
  14.     AutoSeededRandomPool rng;  
  15.     StringSource s1(message, truenew SignerFilter(rng, priv, new HexEncoder(new StringSink(signedMessage))));  
  16.      
  17.     return CString(signedMessage.c_str());  
  18. }  

8.使用公钥验证签名

[cpp]  view plain  copy
  1. bool CKeyController::VerifySignature( const std::string& publicKeyFileName, const std::string& message, const std::string& signedMessage )  
  2. {  
  3.     string decString;  
  4.     FileSource pubFile( publicKeyFileName.c_str(), truenew Base64Decoder(new StringSink(decString)) );  
  5.     RSASSA_PKCS1v15_SHA_Verifier pub;  
  6.   
  7.     HexDecoder decoder;  
  8.     decoder.Put( (byte*)decString.c_str(), decString.size() );  
  9.     decoder.MessageEnd();  
  10.   
  11.     pub.AccessKey().Load(decoder);  
  12.   
  13.     StringSource signatureFile( signedMessage, truenew HexDecoder);  
  14.     if (signatureFile.MaxRetrievable() != pub.SignatureLength())  
  15.     { throw std::string( "Signature Size Problem" ); }  
  16.   
  17.     SecByteBlock signature(pub.SignatureLength());  
  18.     signatureFile.Get(signature, signature.size());  
  19.   
  20.     VerifierFilter *verifierFilter = new VerifierFilter(pub);  
  21.     verifierFilter->Put(signature, pub.SignatureLength());  
  22.     StringSource s(message, true, verifierFilter);  
  23.   
  24.     return verifierFilter->GetLastResult();  
  25. }  

9.测试函数调用

[cpp]  view plain  copy
  1. void CKeyController::testRSA()  
  2. {  
  3.     CString encryptKey = _T("key.pub");  
  4.     CString decryptKey = _T("key.pri");  
  5.     CString seed = _T("seed");  
  6.   
  7.     //GenerateRSAKey( 1024, decryptKey, encryptKey, seed );  
  8.   
  9.     CString message = _T("X3BA-9NSF-8N9Q-UWQC-U7FX-AZZF-JAJW");  
  10.   
  11.     CString encryptedText = RSAEncryptString( encryptKey, seed, message );  
  12.   
  13.     CString decryptedText = RSADecryptString( decryptKey, encryptedText );  
  14.      
  15.     CString signedMessage = SignMessage("key.pri", c2s(decryptedText));  
  16.   
  17.     bool verified = VerifySignature("key.pub", c2s(message), c2s(signedMessage));  
  18. }  

10.工具函数如base64转码,字符串转换

[cpp]  view plain  copy
  1. std::string CKeyController::EncodeBase64( string message )  
  2. {  
  3.     string encode;  
  4.     StringSource(message, truenew Base64Encoder(new StringSink(encode)));  
  5.     return encode;  
  6. }  
  7.   
  8. std::string CKeyController::DecodeBase64( string message )  
  9. {  
  10.     string decode;  
  11.     StringSource(message, truenew Base64Decoder(new StringSink(decode)));  
  12.     return decode;  
  13. }  
  14.   
  15. CString CKeyController::hashString( CString message )  
  16. {  
  17.     string digest;  
  18.     SHA256 hash;  
  19.     StringSource foo(c2s(message), truenew HashFilter(hash, new HexEncoder(new StringSink(digest))));  
  20.     return CString(digest.c_str());  
  21. }  
  22.   
  23. CString CKeyController::hashFile( CString fileName )  
  24. {  
  25.     string digest;  
  26.     SHA256 hash;  
  27.     FileSource(fileName, truenew HashFilter(hash, new HexEncoder(new StringSink(digest))));  
  28.     return CString(digest.c_str());  
  29. }  
  30.   
  31. std::string c2s( CString &cs )  
  32. {  
  33.     CT2CA pszConvertedAnsiString(cs);  
  34.     std::string strStd(pszConvertedAnsiString);  
  35.     return strStd;  
  36. }  
你可以使用Crypto++中的RSA类来导入RSA公钥/私钥的字符串表示。下面是一个简单的示例代码: ```c++ #include <iostream> #include <string> #include <cryptopp/rsa.h> #include <cryptopp/base64.h> using namespace CryptoPP; int main() { // RSA keys in PEM format std::string publicKeyPEM = "-----BEGIN PUBLIC KEY-----\n" "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvRJ9YmJ9A0seV0bSf+I6\n" "n5i6dF6qXl5Hf8b0KJvJ7eN0yTnE4t5rKQYdM+DLg1yXz+4kWv8xgJxJW9Q2gY7L\n" "wNqROnFJZrOq6zZVrWXfR4gWVv8grl2PZl6vQfGbdzPd2BhLW1QOyPZfGy1CCoMg\n" "FQd6ZqBx1UJHsUSx/PnV0i35S8zO7Zq9UxOYbRr9SiCsTJ0FNLwPz7CkC5u3VJ5D\n" "z5z2K7U0fGkO+8fOc5Qv2JUqKd6sN2oT+18+eVf/lvtlQ4U3aXyKZB7u0k8T3xKx\n" "3J2r3x4y+o9B3fz1aV0R/5N5Iz2Kt6gJyJmJyNfh0T+D5JLZL8o+Oq8rD8/8mLgV\n" "XQIDAQAB\n" "-----END PUBLIC KEY-----\n"; std::string privateKeyPEM = "-----BEGIN PRIVATE KEY-----\n" "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCuN1Qa1iRQ9ZvZ\n" "iFfZjzKfKXk9X5Rq8Dp4CCVt1LJbXG8oU1Kd7UeJb+JyQrK+D1hViDUKvC4pDvZL\n" "7Wv8wzZ1mJN+3M+Vc7dqSaTr0z+U4d3ZKQKj1UjF9/3Ud/HXw6Ez84Zx5fX1U7P\n" "3u9Qo+6g0cva0tYcZ8E4m8osjzOZn3n5Z+qoDZ2IuoktDjQOdT7vZJc7JmLQ+6U\n" "Gyf8B4j0c6V7iJ0oqOeq27m2xY6xu9gKwDvZl9zJrFv6f9JQy6yY5ZjXVItK8o+\n" "x3DfX+eD8XO7Z0f1wO3J5lXgBuJop4B3PzZPmZw3jwN3LZwU7hAqjWQvLj5r+DqR\n" "KwvS6TJnAgMBAAECggEBAJv9zZ1N9sN7E+gTt9y/7xFG2PjgB9VjYWg6bd4QKpRq\n" "zGJNj2n8q6k8l7k2uT6sRcO5RhS8bQpO4iLl3GJXZr5kjC0Z/1kE1p4H8Y9e5bDh\n" "gNl3ZnK3Wpli8q7KqUjOY8j6Ktj7+vZnT3sW6v/qpIbQgBn7d3q0qsqzjTm8c5f\n" "V3JzUJqkVJqX1mJmJd6tZslpO8mJyZL/vkC4KszkQeE8xKu6sIiA4r6l5e0+OJ8M\n" "8XmXhV8D8ZcHgKvq7qrBvFq5Xv2mHsLdQO+J7uNLC3iQzY3u4jB6Gk8fN7N3e3jv\n" "dDmf8P0l7dOj6q5sZtqoK6fJjW+PcVnC8KzXUy4YrtkCgYEA3g9W5c7J8KmX3xSU\n" "2p/7VfGzBYC7J1Ll1fz4qWf3XZ2VQF7q6yRrA5X+H2GkZiB3vL8/3gOeO3WuGnI0\n" "bJr1lOY9xMvQj7a6KdC5h4Wvmt3qqh6VdQw7dFx8fJ8x5RQwReOuyZ9nEE5Vf+en\n" "cRg9Uk9LQl3rZ4cazH7c+Lkrj2ECgYEAzL4u8eJ5gCpUvJZJyCmlrJX0GryL1wzE\n" "5zO8m1tjwg1YONyJvR4g4bd7p+56q6v3wTzoumH6x3AWDZC8Z6Jr6i4a8+cnl+9M\n" "P+Jr5Lr2fN2Y7w3dFzHhY5NIR0ZxTQJdC5Jp+el1+Kg2y4eFJZpQz0ueH2Jy6wuz\n" "zqJUQY2RmXUCgYEAwYjQg1FnKPGvJlRrXwL9cO4I3W0gx/kD+LpT8aEguJlRf4uS\n" "ZyN8a+xLZbGzWc5wKT9z3whYf4fXf4aFh2U+ZQzXG7yUa5KdNf7xvP8QXa6omQY0\n" "sQO2e1+Vc1r7h2e0HNY0U6E0g+7l7MBZv5lZP6XG7HdY5k8n1UdbvR9uGkECgYEA\n" "xAIlWc+0qLQUjY7t2sqHjzJ3nV2GxMvW0G9fZgD6loQWtKX2Y7r/x6WLZ9Smc5ZQ\n" "4QJ1l0sT1q2YKqCwR1u+2J9lX8Pp17FZK8Xvq8kPT9lQK9o3+JvUqPvX6xrmJ2mK\n" "R7uxvYv+ZzL2R9gkt/6g1QH0aRZzZj0+6+J5PfWen9sCgYEA7fQxJYJdQdUgJvZL\n" "gH2Y1o5LJ5W1N3v9zQJLJGJ1Tt7TfB3gXzOzL/hsW68Uzr+1JqP6e9LTk5OuWVQG\n" "yR7zFv3p6K5tqT2Z0OJdS4xVw/2zB5YzJiK6I6b5aMZr9o2ZtW/0A1m5RcU6bJSo\n" "Vz5Q5O1ZoD7JdS3d+6iNq+f8dQ==\n" "-----END PRIVATE KEY-----\n"; // Base64 decode the PEM strings std::string publicKeyStr, privateKeyStr; StringSource(publicKeyPEM, true, new Base64Decoder(new StringSink(publicKeyStr))); StringSource(privateKeyPEM, true, new Base64Decoder(new StringSink(privateKeyStr))); // Load the keys from the decoded strings RSA::PublicKey publicKey; RSA::PrivateKey privateKey; StringSource(publicKeyStr, true, new PEMDecoder(new StringSink(publicKey))); StringSource(privateKeyStr, true, new PEMDecoder(new StringSink(privateKey))); return 0; } ``` 在这个示例中,我们将PEM格式的RSA公钥/私钥字符串进行Base64解码,然后使用Crypto++中的PEMDecoder类将它们加载到RSA::PublicKey和RSA::PrivateKey对象中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值