在对固定长度字符串做加密的时候,我们由于知道字符串的长度范围,所以会用到 no padding 的加密方式。
Python2 的 M2Crypto 的 RSA 加密使用比较稳定,而且不同的填充方式用起来也比较统一。
而 Python3 的 RSA 加密模块比较多,而且使用起来不太统一, 而在 no padding 的支持上也比较难找,主流的实现方法都没有介绍,我这里也是费了九牛二虎之力找到了 Python3 中的实现方法。
下面分别介绍 Python2 和 Python3 的实现代码,备份共享。
#!/usr/bin/python2
# -*- coding: utf-8 -*-
author__ = 'owen'
__date__ = '2017-11-22'
import M2Crypto
import base64
ENCRYPT_SALT = b'12345678901234567890123456789012345679801234' # 44 char
RSA_KEY_PATH = '/home/owen/key/'
class MyRSACrypto:
@classmethod
def cryptor( cls, plain_text ):
padding = 3 # no_padding
salt = ENCRYPT_SALT
base_dir = RSA_KEY_PATH
public_key = open( base_dir + 'rsa.pub').read()
# 公钥加密
buf = M2Crypto.BIO.MemoryBuffer('')
buf.write( public_key )
rsa1 = M2Crypto.RSA.load_pub_key_bio( buf )
cipher = rsa1.public_encrypt( plain_text + salt, padding )
rsa_cipher = base64.b64encode( cipher )
return rsa_cipher[:-2]
@classmethod
def decryptor( cls, cipher_text_b64 ):
padding = 3 # no_padding
salt = ENCRYPT_SALT
base_dir = RSA_KEY_PATH
private_key = open( base_dir + 'rsa.pri').read()
# 私钥解密
buf = M2Crypto.BIO.MemoryBuffer('')
buf.write( private_key )
rsa1 = M2Crypto.RSA.load_key_bio( buf )
cipher_text = base64.b64decode( cipher_text_b64 + b"==" )
plain_text = rsa1.private_decrypt( cipher_text, padding )
return plain_text[:20]
if __name__ == '__main__':
text = '31' * 10
cipher_text = MyRSACrypto.cryptor( text )
print(cipher_text)
plain_text = MyRSACrypto.decryptor( cipher_text )
print( plain_text )
author__ = 'owen'
__date__ = '2017-11-22'
import base64
from Crypto.PublicKey import RSA
ENCRYPT_SALT = b'12345678901234567890123456789012345679801234' # 44 char
RSA_KEY_PATH = '/home/owen/key/'
class MyRSACrypto:
@classmethod
def cryptor( cls, plain_text ):
# print("\n================ crypto ========================\n")
if( not isinstance( plain_text, bytes ) ):
plain_text = plain_text.encode()
salt = ENCRYPT_SALT
base_dir = RSA_KEY_PATH
with open(base_dir + 'rsa.pub') as fp:
public_key = fp.read()
if(not public_key):
return None
rsa_cryptor = RSA.importKey( public_key )
plain_text = ( plain_text + salt )
# 无填充方式公钥加密
cipher_text = rsa_cryptor.encrypt( plain_text, 0 )
pad_cnt = 64 - len(cipher_text[0])
cipher_text_rsa = pad_cnt * b'\0' + cipher_text[0]
cipher_text_b64 = base64.b64encode( cipher_text_rsa )
return cipher_text_b64.decode()[:-2]
@classmethod
def decryptor( cls, cipher_text_b64 ):
# print("\n================ decrypto ========================\n")
if( not isinstance( cipher_text_b64, bytes ) ):
cipher_text_b64 = cipher_text_b64.encode()
base_dir = RSA_KEY_PATH
with open( base_dir + 'rsa.pri' ) as fp:
private_key = fp.read()
if(not private_key):
return None
rsa_decryptor = RSA.importKey( private_key )
cipher_text = base64.b64decode( cipher_text_b64 + b"==" )
# 无填充方式私钥解密
plain_text = rsa_decryptor.decrypt( cipher_text )
return plain_text.decode()[:20]
if __name__ == '__main__':
text = '31' * 10
cipher_text = MyRSACrypto.cryptor( text )
print(cipher_text)
plain_text = MyRSACrypto.decryptor( cipher_text )
print( plain_text )