日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2025/3/20 编程问答 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CryptoAPI与openssl RSA非对称加密解密(PKCS1 PADDING)交互 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

(以下代碼中都只做測試用,有些地方沒有釋放內存...這個自己解決下)

1.RSA非對稱的,首先提供一個供測試用的證書和私鑰的數據

1)pem格式的證書和私鑰(公私鑰是對應的)的base64編碼

[cpp] view plaincopyprint?
  • 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");??
  • }??
  • 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?
  • void?readCertBase64(string?&a){??
  • ????a?=?"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\n";??
  • }??
  • 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?
  • 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;??
  • }??
  • 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;}elsecout << "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?
  • 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);??
  • ??
  • ??
  • }??
  • 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?
  • 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;??
  • }??
  • 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?
  • 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);??
  • }??
  • 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?
  • 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);??
  • }??
  • 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_CHECKprintf("CryptDecrypt error:0X%x.\n",GetLastError());return;}printByte(encText,len); }如果到此都沒有什么問題,整個交互就算完成了.

    前一篇提了AES的,還差一個簽名的下回再來討論了

    更多 0

    總結

    以上是生活随笔為你收集整理的CryptoAPI与openssl RSA非对称加密解密(PKCS1 PADDING)交互的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。