(以下代码中都只做测试用,有些地方没有释放内存...这个自己解决下)

1.RSA非对称的,首先提供一个供测试用的证书和私钥的数据

1)pem格式的证书和私钥(公私钥是对应的)的base64编码

[cpp] view plaincopyprint?
  1. void readPriKey(string &a){
  2. a =  "-----BEGIN RSA PRIVATE KEY-----\n";
  3. a.append("MIICXQIBAAKBgQDTFPiHkUX279j7OnK2ToLrwD/QI9N/fL/XoMnW1sBYJdSWs/VP\n");
  4. a.append("5oywvy6yJ0KMpfYcbRCJh2oRbPw7T9IrSHKdOkhB9PF6qwn90xb3Bk22l1LYZNfw\n");
  5. a.append("IQKqRjAXctR8GSC5ULBQmZK2T6m50oD5vl6rD6lnmrQyQSZ3tNNRYbxx/QIDAQAB\n");
  6. a.append("AoGAVqzSzOAzaY3dfHPorMGacvHzgiVj8IKqSAHHP8fZHZkTLXrh7ZhPBzjKFO+Y\n");
  7. a.append("HSb843lJhB+tx1AIVtaVB57tKLHJSrAjFem6mHV+X+JhMeX358QS0QFbUiKfAK5e\n");
  8. a.append("AkM1UdihF/3BX47DZUe44ntRqhffwsNGuZs2tB5FPHIpnGUCQQDvuBumamo+4tff\n");
  9. a.append("oF9Z/iuMJTyDerPgrQbC85ZoHBULLKtnzSUt7pdSsPMMBfImDpquhkLntC+kFV5b\n");
  10. a.append("yXu2nC5bAkEA4Wr1na+izFxmOnppvOjs7eFnch2THvNsajJ+Yl/jnRGGS5CLccrd\n");
  11. a.append("JgUm+j91VUitl88XY/GXAUDIobGw/iAAhwJBANZziODekD/D5cVcDhFPDZwpb7Jb\n");
  12. a.append("ofHcOJFNIv/uJ3FAu/J3lsw5hsxmGnhmFVOwevaoi9AG5RvQNgK9A9zAacMCQQDT\n");
  13. a.append("PI4qVHp0k2nhBvGra4MLcBymXXyOloJUCjlRKpZ7i/6TNULXQcl3ZYCfJXRolRDH\n");
  14. a.append("n/NFXxGoxPK+Q2ue2JJlAkBw1Z/1q2f6JYJ8pLBvdBSmOmKvm+O7x5s0csN7DnXf\n");
  15. a.append("aK1D4/cyCbLdqgogbolQkOwIwUuXLkitW1ldh+MinTMz\n");
  16. a.append("-----END RSA PRIVATE KEY-----\n");
  17. }
  18. void readCert(string &a){
  19. a = "-----BEGIN CERTIFICATE-----\n";
  20. a.append("MIIGVTCCBT2gAwIBAgIKGCyzsAAAAAAAbjANBgkqhkiG9w0BAQUFADA9MRUwEwYK\n");
  21. a.append("CZImiZPyLGQBGRYFbG9jYWwxEzARBgoJkiaJk/IsZAEZFgNpc3MxDzANBgNVBAMT\n");
  22. a.append("BldIVUlTUzAeFw0xMjA0MTEwMTMxNThaFw0xMzA0MTEwMTMxNThaMHIxFTATBgoJ\n");
  23. a.append("kiaJk/IsZAEZFgVsb2NhbDETMBEGCgmSJomT8ixkARkWA2lzczEOMAwGA1UEAxMF\n");
  24. a.append("VXNlcnMxEjAQBgNVBAMMCeWRqOe7jeemuTEgMB4GCSqGSIb3DQEJARYRemhvdXl1\n");
  25. a.append("emh5QDEyNi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANMU+IeRRfbv\n");
  26. a.append("2Ps6crZOguvAP9Aj0398v9egydbWwFgl1Jaz9U/mjLC/LrInQoyl9hxtEImHahFs\n");
  27. a.append("/DtP0itIcp06SEH08XqrCf3TFvcGTbaXUthk1/AhAqpGMBdy1HwZILlQsFCZkrZP\n");
  28. a.append("qbnSgPm+XqsPqWeatDJBJne001FhvHH9AgMBAAGjggOkMIIDoDAdBgNVHQ4EFgQU\n");
  29. a.append("vjfBpRVvsUsaWnX4dC81QzXu5T4wHwYDVR0jBBgwFoAU++PzmmgpwxErxTVrbJp5\n");
  30. a.append("IzqO3RswggECBgNVHR8EgfowgfcwgfSggfGgge6GgbNsZGFwOi8vL0NOPVdIVUlT\n");
  31. a.append("UyxDTj16c3ktMDIxMWMxNWEyNTIsQ049Q0RQLENOPVB1YmxpYyUyMEtleSUyMFNl\n");
  32. a.append("cnZpY2VzLENOPVNlcnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9aXNzLERDPWxv\n");
  33. a.append("Y2FsP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxpc3Q/YmFzZT9vYmplY3RDbGFzcz1j\n");
  34. a.append("UkxEaXN0cmlidXRpb25Qb2ludIY2aHR0cDovL3pzeS0wMjExYzE1YTI1Mi5pc3Mu\n");
  35. a.append("bG9jYWwvQ2VydEVucm9sbC9XSFVJU1MuY3JsMIIBFgYIKwYBBQUHAQEEggEIMIIB\n");
  36. a.append("BDCBowYIKwYBBQUHMAKGgZZsZGFwOi8vL0NOPVdIVUlTUyxDTj1BSUEsQ049UHVi\n");
  37. a.append("bGljJTIwS2V5JTIwU2VydmljZXMsQ049U2VydmljZXMsQ049Q29uZmlndXJhdGlv\n");
  38. a.append("bixEQz1pc3MsREM9bG9jYWw/Y0FDZXJ0aWZpY2F0ZT9iYXNlP29iamVjdENsYXNz\n");
  39. a.append("PWNlcnRpZmljYXRpb25BdXRob3JpdHkwXAYIKwYBBQUHMAKGUGh0dHA6Ly96c3kt\n");
  40. a.append("MDIxMWMxNWEyNTIuaXNzLmxvY2FsL0NlcnRFbnJvbGwvenN5LTAyMTFjMTVhMjUy\n");
  41. a.append("Lmlzcy5sb2NhbF9XSFVJU1MuY3J0MAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgWg\n");
  42. a.append("MD4GCSsGAQQBgjcVBwQxMC8GJysGAQQBgjcVCIbd/wqC4JYWgbmLGoKIvT+HxNMh\n");
  43. a.append("gXGE+cJBg4yVdgIBZAIBBjApBgNVHSUEIjAgBggrBgEFBQcDAgYIKwYBBQUHAwQG\n");
  44. a.append("CisGAQQBgjcKAwQwNQYJKwYBBAGCNxUKBCgwJjAKBggrBgEFBQcDAjAKBggrBgEF\n");
  45. a.append("BQcDBDAMBgorBgEEAYI3CgMEMDsGA1UdEQQ0MDKgHQYKKwYBBAGCNxQCA6APDA16\n");
  46. a.append("c3lAaXNzLmxvY2FsgRF6aG91eXV6aHlAMTI2LmNvbTBEBgkqhkiG9w0BCQ8ENzA1\n");
  47. a.append("MA4GCCqGSIb3DQMCAgIAgDAOBggqhkiG9w0DBAICAIAwBwYFKw4DAgcwCgYIKoZI\n");
  48. a.append("hvcNAwcwDQYJKoZIhvcNAQEFBQADggEBABj0xXhayI5JdqbuyAbqNwzGZxt4X102\n");
  49. a.append("CFFeTU5jauspQjqEpar+/IQ+r3/vf162bY/lLHLpDarFLbZ9dAC6nqNfnE4gg9r7\n");
  50. a.append("p+dbkbzFyBuSTqrzHQ6JgRYSdjwaksHV+uZuP7dfP2HXw4F1T3Ch/7ZKW9+ZlVvd\n");
  51. a.append("QCygAu0z+TS2e7oRFb+swQLVKda8kPTM/b69+r/xdTHXY6+CkfVAk4oYBB56a9AD\n");
  52. a.append("t1XOoAUa42fJdit6+7ssLLTZkZLNsQl6qsuTdv64dIMda4C6NnUsKDfjWGa+0vs3\n");
  53. a.append("VjVNsUC5jo4qRc4XmBvJIx6e5M420sPj2Gi/+ssgmaXK+zUWzowIoMU=\n");
  54. a.append("-----END CERTIFICATE-----\n");
  55. }
void readPriKey(string &a){
a =  "-----BEGIN RSA PRIVATE KEY-----\n";
a.append("MIICXQIBAAKBgQDTFPiHkUX279j7OnK2ToLrwD/QI9N/fL/XoMnW1sBYJdSWs/VP\n");
a.append("5oywvy6yJ0KMpfYcbRCJh2oRbPw7T9IrSHKdOkhB9PF6qwn90xb3Bk22l1LYZNfw\n");
a.append("IQKqRjAXctR8GSC5ULBQmZK2T6m50oD5vl6rD6lnmrQyQSZ3tNNRYbxx/QIDAQAB\n");
a.append("AoGAVqzSzOAzaY3dfHPorMGacvHzgiVj8IKqSAHHP8fZHZkTLXrh7ZhPBzjKFO+Y\n");
a.append("HSb843lJhB+tx1AIVtaVB57tKLHJSrAjFem6mHV+X+JhMeX358QS0QFbUiKfAK5e\n");
a.append("AkM1UdihF/3BX47DZUe44ntRqhffwsNGuZs2tB5FPHIpnGUCQQDvuBumamo+4tff\n");
a.append("oF9Z/iuMJTyDerPgrQbC85ZoHBULLKtnzSUt7pdSsPMMBfImDpquhkLntC+kFV5b\n");
a.append("yXu2nC5bAkEA4Wr1na+izFxmOnppvOjs7eFnch2THvNsajJ+Yl/jnRGGS5CLccrd\n");
a.append("JgUm+j91VUitl88XY/GXAUDIobGw/iAAhwJBANZziODekD/D5cVcDhFPDZwpb7Jb\n");
a.append("ofHcOJFNIv/uJ3FAu/J3lsw5hsxmGnhmFVOwevaoi9AG5RvQNgK9A9zAacMCQQDT\n");
a.append("PI4qVHp0k2nhBvGra4MLcBymXXyOloJUCjlRKpZ7i/6TNULXQcl3ZYCfJXRolRDH\n");
a.append("n/NFXxGoxPK+Q2ue2JJlAkBw1Z/1q2f6JYJ8pLBvdBSmOmKvm+O7x5s0csN7DnXf\n");
a.append("aK1D4/cyCbLdqgogbolQkOwIwUuXLkitW1ldh+MinTMz\n");
a.append("-----END RSA PRIVATE KEY-----\n");
}
void readCert(string &a){
a = "-----BEGIN CERTIFICATE-----\n";
a.append("MIIGVTCCBT2gAwIBAgIKGCyzsAAAAAAAbjANBgkqhkiG9w0BAQUFADA9MRUwEwYK\n");
a.append("CZImiZPyLGQBGRYFbG9jYWwxEzARBgoJkiaJk/IsZAEZFgNpc3MxDzANBgNVBAMT\n");
a.append("BldIVUlTUzAeFw0xMjA0MTEwMTMxNThaFw0xMzA0MTEwMTMxNThaMHIxFTATBgoJ\n");
a.append("kiaJk/IsZAEZFgVsb2NhbDETMBEGCgmSJomT8ixkARkWA2lzczEOMAwGA1UEAxMF\n");
a.append("VXNlcnMxEjAQBgNVBAMMCeWRqOe7jeemuTEgMB4GCSqGSIb3DQEJARYRemhvdXl1\n");
a.append("emh5QDEyNi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANMU+IeRRfbv\n");
a.append("2Ps6crZOguvAP9Aj0398v9egydbWwFgl1Jaz9U/mjLC/LrInQoyl9hxtEImHahFs\n");
a.append("/DtP0itIcp06SEH08XqrCf3TFvcGTbaXUthk1/AhAqpGMBdy1HwZILlQsFCZkrZP\n");
a.append("qbnSgPm+XqsPqWeatDJBJne001FhvHH9AgMBAAGjggOkMIIDoDAdBgNVHQ4EFgQU\n");
a.append("vjfBpRVvsUsaWnX4dC81QzXu5T4wHwYDVR0jBBgwFoAU++PzmmgpwxErxTVrbJp5\n");
a.append("IzqO3RswggECBgNVHR8EgfowgfcwgfSggfGgge6GgbNsZGFwOi8vL0NOPVdIVUlT\n");
a.append("UyxDTj16c3ktMDIxMWMxNWEyNTIsQ049Q0RQLENOPVB1YmxpYyUyMEtleSUyMFNl\n");
a.append("cnZpY2VzLENOPVNlcnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9aXNzLERDPWxv\n");
a.append("Y2FsP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxpc3Q/YmFzZT9vYmplY3RDbGFzcz1j\n");
a.append("UkxEaXN0cmlidXRpb25Qb2ludIY2aHR0cDovL3pzeS0wMjExYzE1YTI1Mi5pc3Mu\n");
a.append("bG9jYWwvQ2VydEVucm9sbC9XSFVJU1MuY3JsMIIBFgYIKwYBBQUHAQEEggEIMIIB\n");
a.append("BDCBowYIKwYBBQUHMAKGgZZsZGFwOi8vL0NOPVdIVUlTUyxDTj1BSUEsQ049UHVi\n");
a.append("bGljJTIwS2V5JTIwU2VydmljZXMsQ049U2VydmljZXMsQ049Q29uZmlndXJhdGlv\n");
a.append("bixEQz1pc3MsREM9bG9jYWw/Y0FDZXJ0aWZpY2F0ZT9iYXNlP29iamVjdENsYXNz\n");
a.append("PWNlcnRpZmljYXRpb25BdXRob3JpdHkwXAYIKwYBBQUHMAKGUGh0dHA6Ly96c3kt\n");
a.append("MDIxMWMxNWEyNTIuaXNzLmxvY2FsL0NlcnRFbnJvbGwvenN5LTAyMTFjMTVhMjUy\n");
a.append("Lmlzcy5sb2NhbF9XSFVJU1MuY3J0MAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgWg\n");
a.append("MD4GCSsGAQQBgjcVBwQxMC8GJysGAQQBgjcVCIbd/wqC4JYWgbmLGoKIvT+HxNMh\n");
a.append("gXGE+cJBg4yVdgIBZAIBBjApBgNVHSUEIjAgBggrBgEFBQcDAgYIKwYBBQUHAwQG\n");
a.append("CisGAQQBgjcKAwQwNQYJKwYBBAGCNxUKBCgwJjAKBggrBgEFBQcDAjAKBggrBgEF\n");
a.append("BQcDBDAMBgorBgEEAYI3CgMEMDsGA1UdEQQ0MDKgHQYKKwYBBAGCNxQCA6APDA16\n");
a.append("c3lAaXNzLmxvY2FsgRF6aG91eXV6aHlAMTI2LmNvbTBEBgkqhkiG9w0BCQ8ENzA1\n");
a.append("MA4GCCqGSIb3DQMCAgIAgDAOBggqhkiG9w0DBAICAIAwBwYFKw4DAgcwCgYIKoZI\n");
a.append("hvcNAwcwDQYJKoZIhvcNAQEFBQADggEBABj0xXhayI5JdqbuyAbqNwzGZxt4X102\n");
a.append("CFFeTU5jauspQjqEpar+/IQ+r3/vf162bY/lLHLpDarFLbZ9dAC6nqNfnE4gg9r7\n");
a.append("p+dbkbzFyBuSTqrzHQ6JgRYSdjwaksHV+uZuP7dfP2HXw4F1T3Ch/7ZKW9+ZlVvd\n");
a.append("QCygAu0z+TS2e7oRFb+swQLVKda8kPTM/b69+r/xdTHXY6+CkfVAk4oYBB56a9AD\n");
a.append("t1XOoAUa42fJdit6+7ssLLTZkZLNsQl6qsuTdv64dIMda4C6NnUsKDfjWGa+0vs3\n");
a.append("VjVNsUC5jo4qRc4XmBvJIx6e5M420sPj2Gi/+ssgmaXK+zUWzowIoMU=\n");
a.append("-----END CERTIFICATE-----\n");
}

2)CryptoAPI和openssl公私钥保持一致,去掉pem头尾直接用便是,没有加密

证书的:

[cpp] view plaincopyprint?
  1. void readCertBase64(string &a){
  2. a = "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\n";
  3. }
void readCertBase64(string &a){
a = "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\n";
}

因为尝试私钥没有导入成功,暂且不管,关于这一点待会再说验证交互成功的替换方案

2.先来看下openssl的RSA实现方案,openssl本身提供了许多的padding方式,

因为CryptoAPI只提供了PKCS1和OAEP两种补齐方式,默认使用的PKCS1,那这里就用PKCS1来验证吧

1)首先需要导入证书和私钥,用于后续加密解密,这里就直接采用通过Base64码来导入

[cpp] view plaincopyprint?
  1. EVP_PKEY * importKey(){
  2. OpenSSL_add_all_algorithms();
  3. EVP_PKEY *prikey;
  4. string a = "";
  5. readPriKey(a);//获取私钥的base64码
  6. const char* sPriKey = a.c_str();
  7. BIO* bio = BIO_new_mem_buf((void*)sPriKey,strlen(sPriKey));//通过BIO放入内存
  8. prikey = PEM_read_bio_PrivateKey(bio,NULL,NULL,NULL);//读取bio,获取私钥对象
  9. BYTE* sign_value = (BYTE*)malloc(1024);
  10. unsigned int len;
  11. return prikey;
  12. }
  13. EVP_PKEY * importCert(){
  14. X509* cert;
  15. OpenSSL_add_all_algorithms();
  16. string a = "";
  17. readCert(a);//证书的base64码
  18. const char* sCert = a.c_str();
  19. BIO* bio = BIO_new_mem_buf((void*)sCert,strlen(sCert));//存到内存
  20. cert = PEM_read_bio_X509(bio,NULL,NULL,NULL);//读取bio,获取证书对象
  21. EVP_PKEY* evp_pubKey =X509_get_pubkey(cert);//获取证书的公钥
  22. int len;
  23. if(evp_pubKey){
  24. return evp_pubKey;
  25. }
  26. else
  27. cout << "evp_pubKey == NULL" << endl;
  28. return NULL;
  29. }
EVP_PKEY * importKey(){
OpenSSL_add_all_algorithms();
EVP_PKEY *prikey;
string a = "";
readPriKey(a);//获取私钥的base64码
const char* sPriKey = a.c_str();
BIO* bio = BIO_new_mem_buf((void*)sPriKey,strlen(sPriKey));//通过BIO放入内存
prikey = PEM_read_bio_PrivateKey(bio,NULL,NULL,NULL);//读取bio,获取私钥对象
BYTE* sign_value = (BYTE*)malloc(1024);
unsigned int len;
return prikey;
}
EVP_PKEY * importCert(){
X509* cert;
OpenSSL_add_all_algorithms();
string a = "";
readCert(a);//证书的base64码
const char* sCert = a.c_str();
BIO* bio = BIO_new_mem_buf((void*)sCert,strlen(sCert));//存到内存
cert = PEM_read_bio_X509(bio,NULL,NULL,NULL);//读取bio,获取证书对象
EVP_PKEY* evp_pubKey =X509_get_pubkey(cert);//获取证书的公钥
int len;
if(evp_pubKey){
return evp_pubKey;
}
else
cout << "evp_pubKey == NULL" << endl;
return NULL;
}

2)有了公钥,私钥对象,接下来做非对称加密和解密就简单些了

这里得提下补齐方式,因为和CryptoAPI的补齐方式要保持一致,折腾了许多时间

CryptoAPI的默认补齐方式是PKCS1,我先以为就是NO_PADDING,结果发现CryptoAPI貌似就没有对NO_PADDING的支持

openssl有NO_PADDING的支持,如果使用这个方式,最好自己将剩余位全部补上规律的数据,便于解密后容易获取到要的明文

NO_PADDING就必须明文和密钥大小一样了,1024位RSA对应128字节明文

PKCS1的得减去11字节存储PKCS1自己的数据,1024位RSA只能加密117字节明文

OAEP则得减去41字节,只能加密87字节明文

如果超过大小,当然可以自己去分节处理,这里就不予讨论了

[cpp] view plaincopyprint?
  1. void evelop(EVP_PKEY* evp_pubKey/*公钥对象*/,BYTE** out/*加密结果*/,unsigned int &cOut/*加密结果大小*/,const BYTE* in/*明文*/,unsigned int cIn/*明文大小*/){
  2. OpenSSL_add_all_algorithms();
  3. bool hasErr = true;
  4. EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(evp_pubKey,NULL);
  5. if(!ctx)
  6. goto err;
  7. if(EVP_PKEY_encrypt_init(ctx)<=0)
  8. goto err;
  9. if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)//设置补齐方式
  10. goto err;
  11. if(EVP_PKEY_encrypt(ctx,NULL,&cOut,in,cIn)<=0)//得到加密的长度,一般都是跟密钥一样长,1024位的RSA密钥就是128字节
  12. goto err;
  13. *out =(BYTE*) OPENSSL_malloc(cOut);
  14. if(!out)
  15. goto err;
  16. if(EVP_PKEY_encrypt(ctx,*out,&cOut,in,cIn)<=0)//得到加密结果
  17. goto err;
  18. cout << "加密成功!" << endl;
  19. hasErr = false;
  20. err:
  21. EVP_PKEY_CTX_free(ctx);
  22. if(!hasErr)
  23. return;
  24. return;
  25. }
  26. void develop(EVP_PKEY* priKey,BYTE** out,unsigned int &cOut, BYTE* data,unsigned int cData){
  27. OpenSSL_add_all_algorithms();
  28. bool hasErr = true;
  29. EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(priKey,NULL);
  30. if(!ctx)
  31. goto err;
  32. if (EVP_PKEY_decrypt_init(ctx) <= 0)
  33. goto err;
  34. if(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)//与加密同样的PKCS1补齐
  35. goto err;
  36. if (EVP_PKEY_decrypt(ctx, NULL, &cOut, data, cData) <= 0)//解密结果大小
  37. goto err;
  38. *out =(BYTE*) OPENSSL_malloc(cOut);//分配内存
  39. if (!out)
  40. goto err;
  41. if (EVP_PKEY_decrypt(ctx, *out, &cOut, data, cData) <= 0)//得到解密结果
  42. goto err;
  43. hasErr = false;
  44. err://输出一些错误信息,偶尔错误信息得不到,只得到一些文件名和所在行,就跑到源代码去找...麻烦死了,如果有好的方案求回复~
  45. EVP_PKEY_CTX_free(ctx);
  46. if(!hasErr)
  47. return;
  48. cout << "err in develop" << endl;
  49. const      char*file,*data1,*efunc,*elib,*ereason,*p;
  50. int                         line,flags;
  51. unsigned long  errn;
  52. errn=ERR_peek_error_line_data(&file,&line,&data1,&flags);
  53. printf("ERR_peek_error_line_data err : %ld,file :%s,line :%d,data :%s\n",errn,file,line,data1);
  54. }
void evelop(EVP_PKEY* evp_pubKey/*公钥对象*/,BYTE** out/*加密结果*/,unsigned int &cOut/*加密结果大小*/,const BYTE* in/*明文*/,unsigned int cIn/*明文大小*/){
OpenSSL_add_all_algorithms();
bool hasErr = true;
EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(evp_pubKey,NULL);
if(!ctx)
goto err;
if(EVP_PKEY_encrypt_init(ctx)<=0)
goto err;
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)//设置补齐方式
goto err;
if(EVP_PKEY_encrypt(ctx,NULL,&cOut,in,cIn)<=0)//得到加密的长度,一般都是跟密钥一样长,1024位的RSA密钥就是128字节
goto err;
*out =(BYTE*) OPENSSL_malloc(cOut);
if(!out)
goto err;
if(EVP_PKEY_encrypt(ctx,*out,&cOut,in,cIn)<=0)//得到加密结果
goto err;
cout << "加密成功!" << endl;
hasErr = false;
err:
EVP_PKEY_CTX_free(ctx);
if(!hasErr)
return;
return;
}
void develop(EVP_PKEY* priKey,BYTE** out,unsigned int &cOut, BYTE* data,unsigned int cData){
OpenSSL_add_all_algorithms();
bool hasErr = true;
EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(priKey,NULL);
if(!ctx)
goto err;
if (EVP_PKEY_decrypt_init(ctx) <= 0)
goto err;
if(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)//与加密同样的PKCS1补齐
goto err;
if (EVP_PKEY_decrypt(ctx, NULL, &cOut, data, cData) <= 0)//解密结果大小
goto err;
*out =(BYTE*) OPENSSL_malloc(cOut);//分配内存
if (!out)
goto err;
if (EVP_PKEY_decrypt(ctx, *out, &cOut, data, cData) <= 0)//得到解密结果
goto err;
hasErr = false;
err://输出一些错误信息,偶尔错误信息得不到,只得到一些文件名和所在行,就跑到源代码去找...麻烦死了,如果有好的方案求回复~
EVP_PKEY_CTX_free(ctx);
if(!hasErr)
return;
cout << "err in develop" << endl;
const      char*file,*data1,*efunc,*elib,*ereason,*p;
int                         line,flags;
unsigned long  errn;
errn=ERR_peek_error_line_data(&file,&line,&data1,&flags);
printf("ERR_peek_error_line_data err : %ld,file :%s,line :%d,data :%s\n",errn,file,line,data1);
}

3)自己测试下上面的代码吧,应该是没问题的

2.CryptoAPI的RSA非对称加密

1)首先依然是公私钥数据问题

这里先看下通过base64导入证书吧,私钥的问题放在第三部分再讨论

[cpp] view plaincopyprint?
  1. PCCERT_CONTEXT  importCryptoCert(string base64Cert){
  2. PCCERT_CONTEXT  pCertContext = NULL;
  3. int len;
  4. BYTE* certEncoded = Base64::base64_decode(base64Cert,len);//BASE64解码,很多方式,先前博文中有代码
  5. if(pCertContext = CertCreateCertificateContext(
  6. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  7. certEncoded,
  8. len)) //直接就通过字节数组导入成证书上下文对象了
  9. {
  10. printf("A new certificate has been created.\n");
  11. }
  12. else
  13. {
  14. printf("A new certificate could not be created.\n");
  15. }
  16. return pCertContext;
  17. }
PCCERT_CONTEXT  importCryptoCert(string base64Cert){
PCCERT_CONTEXT  pCertContext = NULL;
int len;
BYTE* certEncoded = Base64::base64_decode(base64Cert,len);//BASE64解码,很多方式,先前博文中有代码
if(pCertContext = CertCreateCertificateContext(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
certEncoded,
len)) //直接就通过字节数组导入成证书上下文对象了
{
printf("A new certificate has been created.\n");
}
else
{
printf("A new certificate could not be created.\n");
}
return pCertContext;
}

2)公钥加密,CryptoAPI的公钥加密也做了一些封装,没注意到的话得折腾好长时间

我使用的CryptEncrypt,而加密结果是以 little-endian  排列的字节数组,openssl则与其相反

关于CryptoAPI的说明,remark最后一句话,很小的字....

[cpp] view plaincopyprint?
  1. void encryptByPubKey(HCRYPTPROV hProv,PCCERT_CONTEXT cert,BYTE* text,unsigned long &len){
  2. HCRYPTKEY hKey;
  3. CERT_PUBLIC_KEY_INFO pubKeyInfo = cert->pCertInfo->SubjectPublicKeyInfo;//拿到公钥信息
  4. if(!CryptImportPublicKeyInfoEx(hProv,X509_ASN_ENCODING,&pubKeyInfo,CALG_RSA_KEYX,0,NULL,&hKey))//导入,获取公钥对象
  5. {
  6. printf("CryptImportPublicKeyInfoEx error:0X%x.\n",GetLastError());
  7. return;
  8. }
  9. if(!CryptEncrypt(hKey,NULL,true,0,text,&len,128))//加密,padding参数为0,默认就是PKCS1的,不用管了,最后一个参数为128,是对于1024位RSA密钥,明文text得分配128个字节
  10. {
  11. printf("CryptEncrypt error:0X%x.\n",GetLastError());
  12. return;
  13. }
  14. //以下将密文倒序,如果你在openssl倒序了,那这里就不用了,反正CryptoAPI和openssl本身的排列方式就是反的
  15. for(int i = 0 ; i < len / 2;i++)
  16. {
  17. BYTE temp = text[i];
  18. text[i] = text[len - i - 1];
  19. text[len - i - 1] = temp;
  20. }
  21. printByte(text,len);
  22. }
void encryptByPubKey(HCRYPTPROV hProv,PCCERT_CONTEXT cert,BYTE* text,unsigned long &len){
HCRYPTKEY hKey;
CERT_PUBLIC_KEY_INFO pubKeyInfo = cert->pCertInfo->SubjectPublicKeyInfo;//拿到公钥信息
if(!CryptImportPublicKeyInfoEx(hProv,X509_ASN_ENCODING,&pubKeyInfo,CALG_RSA_KEYX,0,NULL,&hKey))//导入,获取公钥对象
{
printf("CryptImportPublicKeyInfoEx error:0X%x.\n",GetLastError());
return;
}
if(!CryptEncrypt(hKey,NULL,true,0,text,&len,128))//加密,padding参数为0,默认就是PKCS1的,不用管了,最后一个参数为128,是对于1024位RSA密钥,明文text得分配128个字节
{
printf("CryptEncrypt error:0X%x.\n",GetLastError());
return;
}
//以下将密文倒序,如果你在openssl倒序了,那这里就不用了,反正CryptoAPI和openssl本身的排列方式就是反的
for(int i = 0 ; i < len / 2;i++)
{
BYTE temp = text[i];
text[i] = text[len - i - 1];
text[len - i - 1] = temp;
}
printByte(text,len);
}

3)试下这个部分的加密吧,能够被openssl解密就没问题了

3.以上只试了CryptoAPI加密openssl解密,因为私钥没导入成功的关系,也没时间再去尝试了,暂且换一种替代方案来测试

如果CryptoAPI解密了CryptoAPI加密的,那这个也是等价的,那干脆直接从windows密钥库获取公私钥,用CryptoAPI直接做加密解密

从windows库获取证书就不在这讨论了,看下私钥解密的部分

[cpp] view plaincopyprint?
  1. void decryptByPriKey(PCCERT_CONTEXT cert,BYTE* encText,unsigned long len){
  2. //将结果再反序一次,用于CryptoAPI自己解密
  3. for(int i = 0 ; i < len / 2;i++)
  4. {
  5. BYTE temp = encText[i];
  6. encText[i] = encText[len - i - 1];
  7. encText[len - i - 1] = temp;
  8. }
  9. HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hKeyProv;
  10. DWORD *dwKeyType;
  11. BOOL bFreeKeyProv = FALSE;
  12. if(!CryptAcquireCertificatePrivateKey(cert, 0, 0, &hKeyProv, dwKeyType, &bFreeKeyProv))  //获取证书对应的私钥句柄
  13. {
  14. printf("CryptAcquireCertificatePrivateKey error:0X%x.\n",GetLastError());
  15. return;
  16. }
  17. HCRYPTKEY hKey;
  18. if(!CryptGetUserKey(hKeyProv,AT_KEYEXCHANGE,&hKey))//通过句柄获取私钥对象
  19. {
  20. printf("CryptGetUserKey error:0X%x.\n",GetLastError());
  21. return;
  22. }
  23. if(!CryptDecrypt(hKey,NULL,true,0,encText,&len)){//解密,也可以把padding参数换成CRYPT_DECRYPT_RSA_NO_PADDING_CHECK
  24. printf("CryptDecrypt error:0X%x.\n",GetLastError());
  25. return;
  26. }
  27. printByte(encText,len);
  28. }
void decryptByPriKey(PCCERT_CONTEXT cert,BYTE* encText,unsigned long len){
//将结果再反序一次,用于CryptoAPI自己解密
for(int i = 0 ; i < len / 2;i++)
{
BYTE temp = encText[i];
encText[i] = encText[len - i - 1];
encText[len - i - 1] = temp;
}
HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hKeyProv;
DWORD *dwKeyType;
BOOL bFreeKeyProv = FALSE;
if(!CryptAcquireCertificatePrivateKey(cert, 0, 0, &hKeyProv, dwKeyType, &bFreeKeyProv))  //获取证书对应的私钥句柄
{
printf("CryptAcquireCertificatePrivateKey error:0X%x.\n",GetLastError());
return;
}
HCRYPTKEY hKey;
if(!CryptGetUserKey(hKeyProv,AT_KEYEXCHANGE,&hKey))//通过句柄获取私钥对象
{
printf("CryptGetUserKey error:0X%x.\n",GetLastError());
return;
}
if(!CryptDecrypt(hKey,NULL,true,0,encText,&len)){//解密,也可以把padding参数换成CRYPT_DECRYPT_RSA_NO_PADDING_CHECK
printf("CryptDecrypt error:0X%x.\n",GetLastError());
return;
}
printByte(encText,len);
}

如果到此都没有什么问题,整个交互就算完成了.

前一篇提了AES的,还差一个签名的下回再来讨论了

更多 0

CryptoAPI与openssl RSA非对称加密解密(PKCS1 PADDING)交互相关推荐

  1. java rsa 117_java实现RSA非对称加密解密

    之前写过一篇java实现AES对称加密解密 在对密码加密传输的场景下 RSA非对称加密解密可能会更加适合. 原理就是后台生成一对公钥和私钥,公钥给前端用来加密,后台用私钥去解密,保证了传输过程中就算被 ...

  2. RSA非对称加密解密概念

    1.RSA加密解密在线计算网站 网站1:https://www.bejson.com/enc/rsa/ 网站2:https://the-x.cn/cryptography/Rsa.aspx 2.PKC ...

  3. 工具类:登录密码的加解密(jsencrypt实现前端RSA非对称加密解密

    定义工具类:utils/jsenscrypt.js import JSEncrypt from 'jsencrypt/bin/jsencrypt.min'// 密钥对生成 http://web.cha ...

  4. Vue与Spring boot基于RSA非对称加密进行前后端交互

    当处理大型的系统项目,或者保密性要求高的项目.是要解除一些加密算法的,非对称加密肯定比对称加密更加安全,但是也更消耗性能.这里就展示一下前端使用Vue,后端使用Spring boot的情况下,进行前后 ...

  5. php signature解密,openssl RSA非对称加密、解密、签名、验签

    需要先了解的openssl系列函数 openssl_pkey_get_private 从证书中解析获取私钥,以供使用.成功,返回真实的密钥资源标识符(Resource ID),否则返回false op ...

  6. RSA非对称加密解密实现

    1.公钥私钥生成工具 参考: http://web.chacuo.net/netrsakeypair 2.python实现 import base64from Crypto.PublicKey imp ...

  7. Springboot+RSA非对称加密

    这是百度百科对(对称加密丶非对称加密)的解释: (1)对称加密算法在加密和解密时使用的是同一个秘钥. (2)非对称加密算法需要两个密钥来进行加密和解密,这两个秘钥是公开密钥(public key,简称 ...

  8. rsa大数加密c语言,C语言:基于OpenSSL-RSA实现RSA非对称加解密

    关于OpenSSL的介绍和安装在此不多赘述,可以在网上找到很多相关资料,各位感兴趣可以去了解下(自觉对OpenSSL开源库只是初级使用阶段,也就不在此"秀下限"了),直接进入主题, ...

  9. Python代码实现MD5、AES对称加密和RSA非对称加密以及OpenSSl实践

    1.MD5加密算法 1.1 MD5加密的特点 不可逆运算 对不同的数据加密的结果是定长的32位和16位字符(不管文件多大都一样) 对相同的数据加密,得到的结果是一样的(也就是复制). 抗修改性 :信息 ...

最新文章

  1. Jfinal 不同版本下的前端模版的数据取值输出
  2. 参加51CTO组织的2013云计算架构师大会
  3. python matplotlib数据可视化_Python - matplotlib 数据可视化
  4. 强制删除页面上出错的WebParts
  5. 20145201 20145227 《信息安全系统设计基础》实验二 固件开发
  6. 《计算机网络》学习笔记 ·006【应用层】
  7. neoterm如何安装python_NeoTerm官方版v2.1.0下载_NeoTerm(21世纪的终端)下载-刷机之家
  8. java中 this详解
  9. 干货 | 挖掘旅游热点吸引年轻人,携程自动热点投放系统的背后玩法
  10. js:简单的盒子碰撞
  11. numpy矩阵升维,拼接
  12. Tapestry介绍
  13. 以AI赋能企业数智化转型 容联“云端”服贸会完美收官
  14. iPhoneX、iPhoneXS、iPhoneXR、iPhoneXSMax屏幕适配尺寸@media
  15. 达梦误删除表空间文件恢复
  16. 麻省理工学院智能探索计划,旨在探索人类智力基础
  17. Chrome主页被劫持怎么破
  18. JAVA实现闯关小游戏(一)
  19. 滑动平均值滤波的VERILOG实现
  20. postgre 数组类型

热门文章

  1. oracle层次查询中prior与自上而下、自下而上查询
  2. JDBC连接mysql--学习目录
  3. php高性能sqllite,简洁的PHP操作SQLite类
  4. 经典面试题:给两个序列如何构造一棵二叉树
  5. 快速幂模板(java)
  6. Java中同时输入字符串和int类型出错的处理方式
  7. 北大OJ百练——4075:矩阵旋转(C语言)
  8. Linux之系统文件管理
  9. java 文件随机读取_Java 实现文件随机读写-RandomAccessFile
  10. python自带编译器闪退_python自带编译器在写入文件时闪退,或者一步步执行到写入时提示8170。解决办法:...