Python pycrypto-长度不正确的密文
我使用pycrypto生成了公钥和私钥,并使用导出密钥将它们保存到文件中:Python pycrypto-长度不正确的密文,python,pycrypto,Python,Pycrypto,我使用pycrypto生成了公钥和私钥,并使用导出密钥将它们保存到文件中: from Crypto.PublicKey import RSA bits=2048 new_key = RSA.generate(bits, e=65537) prv = open('keymac.pem','w') prv.write(new_key.exportKey('PEM')) prv.close() pub = open('pubmac.pem', 'w') pub.write(new_key.publi
from Crypto.PublicKey import RSA
bits=2048
new_key = RSA.generate(bits, e=65537)
prv = open('keymac.pem','w')
prv.write(new_key.exportKey('PEM'))
prv.close()
pub = open('pubmac.pem', 'w')
pub.write(new_key.publickey().exportKey('PEM'))
pub.close()
我使用公钥加密文件(如下)
当我读取文件进行解密时,会得到“长度不正确的密文”
我在Deepal Jayasekara示例的解密代码周围添加了一个try-except块:
try:
encryptedonetimekey = filetodecrypt.read(512)
privatekey = open("keymac.pem", 'r').read()
rsaofprivatekey = RSA.importKey(privatekey)
pkcs1ofprivatekey = PKCS1_OAEP.new(rsaofprivatekey)
aesonetimekey = pkcs1ofprivatekey.decrypt(encryptedonetimekey)
except Exception as decrypprivkeyerr:
print "Decryption of the one time key using the private key failed!!"
print "Key error == %s" %decrypprivkeyerr
raise Exception("Decryption using Private key failed error = %s" %decrypprivkeyerr)
我错过什么了吗?我应该以不同的方式保存私钥吗?我没有正确读取私钥吗 这不会直接回答你的问题,但可能会给你一些问题的线索。Im使用两个函数将内容加密到文件中,而不是直接加密文件。一个用于对文件进行加密(在我的例子中是用户名和密码),然后另一个用于解密数据以根据需要使用 注意填充的需要 在文件中创建加密内容:
from Crypto.Cipher import AES
import base64
import os
import argparse
parser = argparse.ArgumentParser(description='Arguments used to generate new credentials file, Use: -u for username, -p for password')
parser.add_argument('-u', help='Specify username', required=True)
parser.add_argument('-p', help='Specify password', required=True)
parser.add_argument('-b', help='Specify debug', required=False, action='store_true')
args = vars(parser.parse_args())
def encrypt(username, password):
#Encrypt Credentials To '.creds' file, including 'secret' for username and password
dir_path = os.path.dirname(os.path.realpath(__file__))
# the block size for the cipher object; must be 16 per FIPS-197
BLOCK_SIZE = 16
# the character used for padding--with a block cipher such as AES, the value
# you encrypt must be a multiple of BLOCK_SIZE in length. This character is
# used to ensure that your value is always a multiple of BLOCK_SIZE
PADDING = '{'
# one-liner to sufficiently pad the text to be encrypted
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
# generate a random secret key
user_secret = os.urandom(BLOCK_SIZE)
pass_secret = os.urandom(BLOCK_SIZE)
# one-liners to encrypt/encode and decrypt/decode a string
# encrypt with AES, encode with base64
EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
# create a cipher object using the random secret
user_cipher = AES.new(user_secret)
pass_cipher = AES.new(pass_secret)
# encode a string
user_encoded = EncodeAES(user_cipher, username)
pass_encoded = EncodeAES(pass_cipher, password)
try:
with open('.creds', 'w') as filename:
filename.write(user_encoded + '\n')
filename.write(user_secret + '\n')
filename.write(pass_encoded + '\n')
filename.write(pass_secret + '\n')
filename.close()
print '\nFile Written To: ', dir_path + '/.creds'
except Exception, e:
print e
if args['b']:
print((user_encoded, user_secret), (pass_encoded, pass_secret))
username = args['u']
password = args['p']
encrypt(username, password)
解密数据
def decrypt(dir_path, filename):
#Read '.creds' file and return unencrypted credentials (user_decoded, pass_decoded)
lines = [line.rstrip('\n') for line in open(dir_path + filename)]
user_encoded = lines[0]
user_secret = lines[1]
pass_encoded = lines[2]
pass_secret = lines[3]
# the character used for padding--with a block cipher such as AES, the value
# you encrypt must be a multiple of BLOCK_SIZE in length. This character is
# used to ensure that your value is always a multiple of BLOCK_SIZE
PADDING = '{'
DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)
# create a cipher object using the random secret
user_cipher = AES.new(user_secret)
pass_cipher = AES.new(pass_secret)
# decode the encoded string
user_decoded = DecodeAES(user_cipher, user_encoded)
pass_decoded = DecodeAES(pass_cipher, pass_encoded)
return (user_decoded, pass_decoded)
错误消息“长度不正确的密文”告诉了我们所有人。也就是说,
密码文本超出了可由(密钥长度,
1024.2048..)/8. 要解决这个问题,您可以分离密文并解密
将它们放入一个循环中,然后组装所有解密的字节字符串。我的Python 3.6代码供参考:
# 1024/8
default_length = 128
encrypt_str = str(data["content"])
sign_str = str(data["sign"])
try:
rsa_private_key = RSA.importKey(private_key)
encrypt_byte = base64.b64decode(encrypt_str.encode())
length = len(encrypt_byte)
cipher = PKCS115_Cipher(rsa_private_key)
if length < default_length:
decrypt_byte = cipher.decrypt(encrypt_byte, 'failure')
else:
offset = 0
res = []
while length - offset > 0:
if length - offset > default_length:
res.append(cipher.decrypt(encrypt_byte[offset: offset +
default_length], 'failure'))
else:
res.append(cipher.decrypt(encrypt_byte[offset:], 'failure'))
offset += default_length
decrypt_byte = b''.join(res)
decrypted = decrypt_byte.decode()
#1024/8
默认长度=128
加密\u str=str(数据[“内容”])
符号_str=str(数据[“符号”])
尝试:
rsa_private_key=rsa.importKey(私钥)
encrypt_byte=base64.b64解码(encrypt_str.encode())
长度=len(加密字节)
cipher=PKCS115_密码(rsa_私钥)
如果长度<默认长度:
解密字节=密码。解密(加密字节,“失败”)
其他:
偏移量=0
res=[]
当长度-偏移>0时:
如果长度-偏移>默认长度:
res.append(cipher.decrypt)(加密字节[offset:offset+
默认长度],“失败”)
其他:
res.append(cipher.decrypt(加密字节[offset:],'failure'))
偏移量+=默认长度
解密字节=b“”。加入(res)
decrypted=解密字节。decode()
如果您以字节形式读取,请记住用“b”打开,否则请尝试在使用读取字符串之前进行修剪。为什么要将密码文本分成(密钥长度/8)块?为什么具体是8?