0

我目前正在尝试使用 python 密码库和 RSA 加密和解密密码。密钥生成工作正常,加密工作正常,但是在解密密码时,我遇到了这个回溯错误消息:

raise ValueError("Ciphertext length must be equal to key size.")

我的加解密代码如下:

class AppCryptography():

    def generate_rsa_keypair(self, bits=4096):
        return rsa.generate_private_key(
            public_exponent=65537,
            key_size=bits,
            backend=default_backend()
        )

    def load_private_key(self, pem_file_path):

        with open(pem_file_path, "rb") as key_file:
            private_key = serialization.load_pem_private_key(
                key_file.read(),
                password=None,
                backend=default_backend()
            )

        return private_key

    def load_public_key(self, pem_file_path):

        with open(pem_file_path, "rb") as key_file:
            public_key = serialization.load_pem_public_key(
                key_file.read(),
                backend=default_backend()
            )

        return public_key

    def encrypt_password(self, public_key, password):
        password = bytes(password) if not isinstance(password, bytes) else password
        public_key = public_key if isinstance(public_key, RSAPublicKey) else self.load_pem_public_key(
            public_key_pem_export=public_key
        )

        cipher_pass = public_key.encrypt(
            password,
            padding.OAEP(
                mgf=padding.MGF1(algorithm=hashes.SHA1()),
                algorithm=hashes.SHA1(),
                label=None
            )
        )

        return str(base64.b64encode(cipher_pass))

    def decrypt(self, private_key, cipher_pass):
        cipher_pass = base64.b64decode(cipher_pass) if not isinstance(cipher_pass, bytes) else cipher_pass
        private_key = private_key if isinstance(private_key, RSAPrivateKey) else self.load_pem_private_key(
            private_key_pem_export=private_key
        )

        plain_text_pass = private_key.decrypt(
            cipher_pass,
            padding.OAEP(
                mgf=padding.MGF1(algorithm=hashes.SHA1()),
                algorithm=hashes.SHA1(),
                label=None
            )
        )
        return str(plain_text_pass)

当我运行此脚本时会发生错误:

crypter = AppCryptography()

backend_public_key = crypter.load_public_key(dir_path + "/util/keys/backend_public_key.pem")
frontend_private_key = crypter.load_private_key(dir_path + "/util/keys/frontend_private_key.pem")

encrypted_password = crypter.encrypt_password(backend_public_key, password)

signature = crypter.sign_data(frontend_private_key, password)

backend_private_key = crypter.load_private_key(dir_path + "/util/keys/backend_private_key.pem")
cleartext = crypter.decrypt(backend_private_key, encrypted_password)

我的堆栈跟踪显示错误来自解密函数,但我无法看到错误在函数定义中的位置。

File "/Users/Me/anaconda/envs/flask_dream/lib/python2.7/site-packages/sqlalchemy/orm/state.py", line 411, in _initialize_instance
  return manager.original_init(*mixed[1:], **kwargs)
File "/Users/Me/anaconda/envs/flask_dream/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 650, in _declarative_constructor
  setattr(self, k, kwargs[k])
File "/Users/Me/Desktop/Projects/Flask-Dream/project_app/models.py", line 114, in password
  cleartext = crypter.decrypt(backend_private_key, encrypted_password)
File "/Users/Me/Desktop/Projects/Flask-Dream/project_app/util/crypto.py", line 121, in decrypt
  label=None
File "/Users/Me/anaconda/envs/flask_dream/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/rsa.py", line 397, in decrypt
  raise ValueError("Ciphertext length must be equal to key size.")
4

1 回答 1

3

您的代码中似乎存在的问题是以下行:

cipher_pass = base64.b64decode(cipher_pass) if not isinstance(cipher_pass, bytes) else cipher_pass

现在 - 如果我正确理解 Python - 字符串存储在具有特定编码的字节中(这绝对是 Python 2 的情况,并且在str使用 Python 3 时也可能如此)。

这意味着 base64 字符串也是一个字节字符串,并且isinstance(cipher_pass, bytes)返回 true。但这意味着base64解码没有被触发,这反过来意味着你的密文太大,解密时会失败。

如果您需要文本界面,最好始终解码 base64。

于 2017-02-06T01:16:53.697 回答