Python 进行RSA私钥加密,公钥解密

使用M2Crypto库

需要安装M2Crypto库

 
 
  1. # -*- coding: UTF-8 -*-
  2. import M2Crypto
  3. from Crypto.PublicKey import RSA
  4. import base64
  5. import sys
  6. #私钥加密,公钥解密
  7. def pri_encrypt(msg, file_name):
  8. rsa_pri = M2Crypto.RSA.load_key(file_name)
  9. ctxt_pri = rsa_pri.private_encrypt(msg, M2Crypto.RSA.pkcs1_padding) #这里的方法选择加密填充方式,所以在解密的时候 要对应。
  10. ctxt64_pri = ctxt_pri.encode('base64') #密文是base64 方便保存 encode成str
  11. print ('密文:%s'% ctxt64_pri)
  12. return ctxt64_pri
  13. def pub_decrypt_with_pubkeyfile(msg, file_name):
  14. rsa_pub = M2Crypto.RSA.load_pub_key(file_name)
  15. pub_decrypt(msg, rsa_pub)
  16. def pub_decrypt_with_pubkeystr(msg, pub_key):
  17. #将pub_key转成bio对象,再将bio对象转换成公钥对象
  18. bio = M2Crypto.BIO.MemoryBuffer(pub_key)
  19. rsa_pub = M2Crypto.RSA.load_pub_key_bio(bio)
  20. pub_decrypt(msg, rsa_pub)
  21. def pub_decrypt(msg, rsa_pub):
  22. ctxt_pri = msg.decode("base64") # 先将str转成base64
  23. maxlength = 128
  24. output = ''
  25. while ctxt_pri:
  26. input = ctxt_pri[:128]
  27. ctxt_pri = ctxt_pri[128:]
  28. out = rsa_pub.public_decrypt(input, M2Crypto.RSA.pkcs1_padding) #解密
  29. output = output + out
  30. print('明文:%s'% output)
  31. if __name__ == "__main__":
  32. prikey_file = './rsa/rsa_private_key.pem'
  33. pubkey_file = './rsa/rsa_public_key.pem'
  34. msg = 'Test String.'
  35. primsg = pri_encrypt(msg, prikey_file)
  36. pub_decrypt(primsg, pubkey_file)

使用C语言的动态库

decrypt.c

 
 
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <ctype.h>
  5. #include <openssl/rsa.h>
  6. #include <openssl/engine.h>
  7. void decrypt(char *pristr, char *pubkey, int padding, char *pub_str)
  8. {
  9. BIO *bp;
  10. EVP_PKEY *pkey;
  11. int crypted_len, n;
  12. size_t data_len;
  13. char *data, *dest_p, *p, *last, *decrypt_buf, *dest;
  14. char buf[128];
  15. bp = BIO_new_mem_buf((void *)pubkey, -1);
  16. pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL);
  17. BIO_free(bp);
  18. if (!pkey) {
  19. fprintf(stderr, "get public key error\n");
  20. return;
  21. }
  22. crypted_len = EVP_PKEY_size(pkey);
  23. decrypt_buf = malloc(crypted_len + 1);
  24. if (!decrypt_buf) {
  25. fprintf(stderr, "decrypt_buf, malloc error\n");
  26. return;
  27. }
  28. base64_decode(pristr, (unsigned char **)&data, &data_len);
  29. dest = malloc(data_len);
  30. if (!dest) {
  31. fprintf(stderr, "dest, malloc error\n");
  32. free(decrypt_buf);
  33. return;
  34. }
  35. dest_p = dest;
  36. p = data;
  37. last = data + data_len;
  38. do {
  39. n = last - p;
  40. if (n > 128) {
  41. n = 128;
  42. }
  43. bzero(buf, sizeof(buf));
  44. bzero(decrypt_buf, sizeof(decrypt_buf));
  45. memcpy(buf, p, n);
  46. p += n;
  47. crypted_len = RSA_public_decrypt(n, (unsigned char *)buf, decrypt_buf, pkey->pkey.rsa, padding);
  48. if (crypted_len != -1) {
  49. memcpy(dest_p, decrypt_buf, crypted_len);
  50. dest_p += crypted_len;
  51. }
  52. } while (last - p > 0);
  53. *dest_p = 0;
  54. strcpy(pub_str, dest);
  55. free(decrypt_buf);
  56. free(dest);
  57. free(data);
  58. }
  59. size_t calc_decode_len(const char* b64input) {
  60. size_t len = strlen(b64input), padding = 0;
  61. if (b64input[len - 1] == '=' && b64input[len - 2] == '=') {
  62. padding = 2;
  63. } else if (b64input[len - 1] == '=') {
  64. padding = 1;
  65. }
  66. return (size_t) len * 0.75 - padding;
  67. }
  68. int base64_decode(char *b64message, unsigned char **buffer, size_t *len) {
  69. BIO *bio, *b64;
  70. int decode_len = calc_decode_len(b64message);
  71. *buffer = malloc(decode_len);
  72. if (!*buffer) {
  73. fprintf(stderr, "buffer, malloc error\n");
  74. return -1;
  75. }
  76. bio = BIO_new_mem_buf(b64message, -1);
  77. b64 = BIO_new(BIO_f_base64());
  78. bio = BIO_push(b64, bio);
  79. BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
  80. *len = BIO_read(bio, *buffer, strlen(b64message));
  81. BIO_free_all(bio);
  82. if (*len != decode_len) {
  83. return -1;
  84. }
  85. return 0;
  86. }

decrypt.h

 
 
  1. #ifndef __DECRYPT_H__
  2. #define __DECRYPT_H__
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <ctype.h>
  7. #include <openssl/rsa.h>
  8. #include <openssl/engine.h>
  9. void decrypt(char* pristr, char* pubkey, int padding, char* pubstr);
  10. #endif

编译,生成一个动态库文件

 
 
  1. gcc -Wall -fpic -shared -lcrypto decrypt.c -o libdec.so

写一个测试文件进行测试,main.c

 
 
  1. #include "decrypt.h"
  2. #include <stdio.h>
  3. int main()
  4. {
  5. //公钥
  6. char *pkey_str = "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2kcrRvxURhFijDoPpqZ/IgPlA\ngppkKrek6wSrua1zBiGTwHI2f+YCa5vC1JEiIi9uw4srS0OSCB6kY3bP2DGJagBo\nEgj/rYAGjtYJxJrEiTxVs5/GfPuQBYmU0XAtPXFzciZy446VPJLHMPnmTALmIOR5\nDddd1Zklod9IQBMjjwIDAQAB\n-----END PUBLIC KEY-----";
  7. //用私钥加密过的字符串
  8. char *pri_str = "YFSGlJTpNYakrZuZqZ55dcA5mVUb/JQBr3hdDjODsAVSdoVVytIagk9Wt0CD/uX+7jGL9pqev8/u0I0ZBKEmz5huXp8TdZSnskCZ7GTeHNW0VPJcW8OcBxAValA0jQSv2mBP+tc1r6mdvf66GEzhvgBfTnp3Sp7V3dijJ9bNstIDyrGm/BlByhcMr3UqXjTFJaui6t5TxvZhCuSV9sg+xVVA+sR3uFI78b5lKomg5Vu31EBZvXASlFfaOc4StltRUH2aSiRqjnbXe8dlRZO0Ih44htYs2QfehzeQnPHtTwNHUvtVIVcIdI/7j9yfy5es13QeIgfKghY/ENUnB2V7iA==";
  9. char decrypted_buf[10240];
  10. decrypt(pri_str, pkey_str, 1, decrypted_buf);
  11. printf("%s", decrypted_buf);
  12. return 0;
  13. }

编译,测试:

 
 
  1. export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:'pwd'
  2. gcc main.c -o test -L./ -ldec
  3. ./test
  4. [zhangshibo@tuyoo so_test]${"order_id_com":"2013061805870589","amount":"0.10","account":"test","order_id":"2013061800002115","result":"success","user_id":"0"}

在python中使用libdec.so 
注意,需要安装cffi,然后用pypy运行 
test.py

 
 
  1. import os
  2. from cffi import FFI
  3. path = os.path.split(os.path.realpath(__file__))[0]
  4. ffi = FFI()
  5. #引入动态库
  6. lib = ffi.dlopen(path + "/libdec.so")
  7. print('Loaded lib {0}'.format(lib))
  8. #函数声明,类似于C的.h文件
  9. ffi.cdef(
  10. '''
  11. void decrypt(char* pristr, char* pubkey, int padding, char* pubstr);
  12. int printf(const char* format, ...);
  13. '''
  14. )
  15. #公钥
  16. pkey_str = '''-----BEGIN PUBLIC KEY-----
  17. MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2kcrRvxURhFijDoPpqZ/IgPlA
  18. gppkKrek6wSrua1zBiGTwHI2f+YCa5vC1JEiIi9uw4srS0OSCB6kY3bP2DGJagBo
  19. Egj/rYAGjtYJxJrEiTxVs5/GfPuQBYmU0XAtPXFzciZy446VPJLHMPnmTALmIOR5
  20. Dddd1Zklod9IQBMjjwIDAQAB
  21. -----END PUBLIC KEY-----'''
  22. #用私钥加密过的字符串
  23. pri_str = "klzAd6Qu87M/0GdkmmeJbyk/NKuIIRS/M/4GpckMNfe4jwjBc9w38LExpYVvJZ5RKkr2y9Wuj6cZsThqAM0ZDcFZ2Ew2csRZlMnc9kD/yqHHMb0fb6KL3g7DZ3sRAhAIT2MkTDHOVKctxrc5Qcn8Ie2IX1Xgz7G+yvn0j1VYc3xGUbbCxxPjb3MTuDUDFbElPNq98dQufrcFUBsXwVdQJv6+GwE+7N/IJffPA6TNv3aB+AUe7sc/lbKOywxCSb0+rxPkb0mcT6q5O0S1bRIvZqtxQJn0HydqmFYPBYr9X2lzkgGIwZL8oX6vb2YVNHRPoCxKh+10TewAOOlUggbTfA=="
  24. #申请C风格的数组
  25. pub_str = ffi.new("char[]", 10240)
  26. lib.decrypt(pri_str, pkey_str, 1, pub_str)
  27. print pub_str
  28. lib.printf("%s\n", pub_str)
  29. #转换成Python可用的字符串
  30. pystr = ffi.string(pub_str)
  31. print pystr
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Python中使用非对称加密算法实现私钥加密公钥解密的机制。这种加密方式是通过使用一对密钥:公钥私钥,来实现数据加解密的过程。其中,公钥是由私钥经过复杂运算得到的,具有加密能力;而私钥则由密钥持有者自己持有,用于解密数据。这样一来,即便是加密数据不慎泄露,仍然是安全的,因为数据只能由对应的私钥进行解密Python中支持RSA算法,可以用pycryptodome或cryptography库来实现非对称加密。 使用非对称加密算法,首先需要对数据进行加密。这里使用RSA算法作为例子:选择两个不同且较大的质数p,q,计算出n=p*q,然后选取不大于 (p-1)*(q-1) 的数e作为公钥(这里称为公钥指数),计算出对应的私钥d(这里称为私钥指数)。然后,将公钥指数和n组成一个公钥私钥指数和n组成一个私钥加密的过程就是用公钥指数e和n对数据进行加密解密的过程就是用私钥指数d和n对加密数据进行解密Python中可以使用如下代码实现RSA加密解密: ```python # 加密 from Crypto.PublicKey import RSA msg = b'this is a secret message' key = RSA.generate(2048) pub_key = key.publickey() encrypted = pub_key.encrypt(msg, 32) # 解密 decrypted = key.decrypt(encrypted) ``` 需要注意的是,使用RSA算法进行解密可能会涉及到数据长度的限制,因此可以采用数据分块的方式进行解密。另外,在实际使用中,需要确保私钥的安全性,以免遭到泄露而导致数据的不安全。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值