为了账号安全,请及时绑定邮箱和手机立即绑定

ValueError:密文长度必须等于密钥大小

ValueError:密文长度必须等于密钥大小

largeQ 2022-11-01 14:51:51
我知道这个问题被问了很多,但我仍然不明白如何调试我的代码。我在谷歌上搜索这个问题已经超过 3 天了,但我找不到适合我的代码的答案。我想添加带有输入的加密消息,但每次我运行我的代码时它只会给出Traceback (most recent call last):  File "decryption.py", line 27, in <module>    label=None  File "/opt/anaconda3/lib/python3.7/site-packages/cryptography/hazmat/backends/openssl/rsa.py", line 357, in decrypt    raise ValueError("Ciphertext length must be equal to key size.")ValueError: Ciphertext length must be equal to key size.错误。我知道它的标签,但我找不到答案这是我的解密代码:from cryptography.hazmat.backends import default_backendfrom cryptography.hazmat.primitives import serializationfrom cryptography.hazmat.primitives import hashesfrom cryptography.hazmat.primitives.asymmetric import paddingwith open("private_key.pem", "rb") as key_file:    private_key = serialization.load_pem_private_key(        key_file.read(),        password=None,        backend=default_backend()    )with open("public_key.pem", "rb") as key_file:    public_key = serialization.load_pem_public_key(        key_file.read(),        backend=default_backend()    )textInput = str(input(">>> "))encrypted = textInput.encode() original_message = private_key.decrypt(    encrypted,    padding.OAEP(        mgf=padding.MGF1(algorithm=hashes.SHA256()),        algorithm=hashes.SHA256(),        label=None    ))original_decoded_message = original_message.decode("utf-8")print(original_decoded_message)对于加密:from cryptography.hazmat.backends import default_backendfrom cryptography.hazmat.primitives.asymmetric import rsafrom cryptography.hazmat.primitives import hashesfrom cryptography.hazmat.primitives.asymmetric import paddingfrom cryptography.hazmat.primitives import serializationprivate_key = rsa.generate_private_key(    public_exponent=65537,    key_size=2048,    backend=default_backend())public_key = private_key.public_key()我对非对称加密/解密真的很陌生。
查看完整描述

1 回答

?
千万里不及你

TA贡献1784条经验 获得超9个赞

你的代码解密部分的这个小修改使它对我有用:


textInput = str(input(">>> "))

# encrypted = textInput.encode()  #this is incorrect!

encrypted = eval(textInput)

这就是我得到的:


对于加密部分:


>>> test message

b'>xB)\xf1\xc5I\xd6\xce\xfb\xcf\x83\xe2\xc5\x8f\xcfl\xb9\x0f\xa2\x13\xa5\xe1\x03\xf7p\xb3\x9c\xeb\r\xc1"\xf2\x17\x8b\xea\t\xed\xb2xG\xb7\r\xa9\xf8\x03eBD\xdd9>\xbe\xd1O\xe2\x9f\xbb\xf9\xff5\x96l\xea\x17FI\x8d\x02\x05\xea\x1dpM\xbb\x04J\xfc\x0c\\\xfe\x15\x07\xaf \x9e\xc2\xf9M\xa4\x1d$\xc3\x99my\xb6\xc5\xad\x97\xd06\xd2\x08\xd3\xe2\xc8H\xca\xd8\xfd{\xe6\xc6\xa3\x18\xeb\xe6\xcc\xc5\x9a\xc8*\xbb\xc1\x8c\x80,\x1f\r@\x9b\x9d\xc5\x91I\xa8\xc01y\xbc\xa73\xd3\x19;\xef\x8a\xfb\xc2\xc4\x9e\xbe\x8f\xeb\x1d\x12\xbd\xe4<\xa0\xbb\x8d\xef\xee\xa3\x89E\x07"m\x1d\xb0\xf3\xd2:y\xd9\xbd\xef\xdf\xc9\xbb\x1b\xd5\x03\x91\xa4l\x8bS\x9e\x80\x14\x90\x18\xc4\x9e\\?\x8eF\x05\xa1H\x9e:\x0c\x96\x8e\xb3E3\x90\xa2\xa1\xd9\x88\xa0<X\x7f\rIP\x00\xbf\xf6\x15\xfb9tW\x17\x9f\xca\x95\xf6|\xd7\x90\xbcp\xe5\xb5,V\x1b\xe9\x90\xf6\x87 v=6'

现在对于解密部分,我使用输出:


>>> b'>xB)\xf1\xc5I\xd6\xce\xfb\xcf\x83\xe2\xc5\x8f\xcfl\xb9\x0f\xa2\x13\xa5\xe1\x03\xf7p\xb3\x9c\xeb\r\xc1"\xf2\x17\x8b\xea\t\xed\xb2xG\xb7\r\xa9\xf8\x03eBD\xdd9>\xbe\xd1O\xe2\x9f\xbb\xf9\xff5\x96l\xea\x17FI\x8d\x02\x05\xea\x1dpM\xbb\x04J\xfc\x0c\\\xfe\x15\x07\xaf \x9e\xc2\xf9M\xa4\x1d$\xc3\x99my\xb6\xc5\xad\x97\xd06\xd2\x08\xd3\xe2\xc8H\xca\xd8\xfd{\xe6\xc6\xa3\x18\xeb\xe6\xcc\xc5\x9a\xc8*\xbb\xc1\x8c\x80,\x1f\r@\x9b\x9d\xc5\x91I\xa8\xc01y\xbc\xa73\xd3\x19;\xef\x8a\xfb\xc2\xc4\x9e\xbe\x8f\xeb\x1d\x12\xbd\xe4<\xa0\xbb\x8d\xef\xee\xa3\x89E\x07"m\x1d\xb0\xf3\xd2:y\xd9\xbd\xef\xdf\xc9\xbb\x1b\xd5\x03\x91\xa4l\x8bS\x9e\x80\x14\x90\x18\xc4\x9e\\?\x8eF\x05\xa1H\x9e:\x0c\x96\x8e\xb3E3\x90\xa2\xa1\xd9\x88\xa0<X\x7f\rIP\x00\xbf\xf6\x15\xfb9tW\x17\x9f\xca\x95\xf6|\xd7\x90\xbcp\xe5\xb5,V\x1b\xe9\x90\xf6\x87 v=6'

test message

原始代码的问题在于,您将字节字符串的表示形式编写为 unicode 字符串(使用时print(encrypted)),然后在解密代码中将其编码为字节对象,然后将其传递给解密函数。编码此字符串不会产生原始字节字符串encrypted。


这个例子说明了这个问题:


>>> x = bytes(bytearray.fromhex('f3'))

>>> x #A bytes string, similar to encrypt

b'\xf3'

>>> print(x)

b'\xf3'

>>> len(x)

1

>>> str(x) #this is what print(x) writes to stdout

"b'\\xf3'"

>>> print(str(x))

b'\xf3'

>>> len(str(x)) #Note that the lengths are different!

>>> x == str(x)

False

>>> str(x).encode() #what you were trying to do

b"b'\\xf3'"

>>> x == str(x).encode()

False

>>> eval(str(x)) #what gets the desired result

b'\xf3'

>>> x == eval(str(x))

True

问题是该print函数打印对象的表示而不是对象本身。本质上,它通过使用该对象的__repr__or__str__方法获取固有不可打印对象的可打印值来实现这一点。

这是文档__str__

str(object)由内置函数调用,format()print() 计算对象的“非正式”或可很好打印的字符串表示。返回值必须是字符串对象。. . 内置类型对象调用定义的默认实现 object.__repr__()

__repr__

repr()内置函数调用以计算对象的“官方”字符串表示。如果可能的话,这应该看起来像一个有效的 Python 表达式,可以用来重新创建一个对象

返回的这个“官方”表示__repr__允许我eval在解密代码中使用该函数来解决问题。

TL;DR :复制的输出print(encrypted)复制encrypted.__str__()由. 它们不能被编码回(通过使用编码)来创建它们所代表的原始字节字符串。encrypted.__repr__()utf-8utf-8

来自stackoverflow用户的这个问题也值得研究,面临同样的问题。如果需要,答案提供了一种将这种表示实际编码回字节对象的方法。值得研究一下,因为eval应该避免,这是非常不安全的。要使该方法起作用,您必须在对其进行编码之前从字符串中删除前导b'和尾随。'textInput

我的最终建议是通过encrypted使用带有pickle模块的文件或某种形式的套接字编程在两个程序之间传递整个对象。最好不要在程序之间使用printinput传递这样的数据,以避免编码问题。


查看完整回答
反对 回复 2022-11-01
  • 1 回答
  • 0 关注
  • 156 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信