微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

AES GCM 返回“ValueError:MAC 检查失败”

如何解决AES GCM 返回“ValueError:MAC 检查失败”

我正在尝试制作密码管理器,我正在使用 KDF 制作密钥,然后使用 AES GCM 加密数据库中的每一行。每一行都有一个不同的盐用于密钥。我已按照 pycryptodome 上的文档使用示例代码加密和解密数据,除了 MAC 检查外,一切正常。

我检查了多次,加密和解密、随机数、盐、标签、密文等之间的一切都完全相同。

我该如何解决这个问题? (代码如下)

class Crypto(PasswordDatabase):
    def __init__(self):
        PasswordDatabase.__init__(self)
        self.db = None

    def encrypt_db(self):
        self.db = self.get_database()
        master_password = b'password'

        with open("passwords.txt","w") as file:
            for i in range(len(self.db)):

                current_tuple = list(self.db[i])
                del current_tuple[0]
                current_tuple = tuple(current_tuple)
                plaintext = ",".join(current_tuple)

                salt = get_random_bytes(16)
                key = PBKDF2(master_password,salt,16,count=1000000,hmac_hash_module=SHA512)
                file.write(f"salt={salt},")

                header = b"header"
                cipher = AES.new(key,AES.MODE_GCM)
                cipher.update(header)
                ciphertext,tag = cipher.encrypt_and_digest(plaintext.encode())

                json_k = [ 'nonce','header','ciphertext','tag' ]
                json_v = [b64encode(x).decode('utf-8') for x in (cipher.nonce,header,ciphertext,tag)]
                result = json.dumps(dict(zip(json_k,json_v)))

                print(result,"\n")
                file.write(result + "\n")

    def decrypt_db(self):
        with open("passwords.txt","r") as file:
            master_password = b"password"

            for line in file:
                stripped_line = line.strip()
                ssalt = re.findall("salt=(b'.*'),",str(stripped_line))
                salt = ssalt[0]

                key = PBKDF2(master_password,hmac_hash_module=SHA512)

                json_input = re.findall("salt=b'.*',({.*})",str(stripped_line))
                b64 = json.loads(json_input[0])
                json_k = [ 'nonce','tag' ]
                jv = {k:b64decode(b64[k]) for k in json_k}

                cipher = AES.new(key,AES.MODE_GCM,nonce=jv['nonce'])
                cipher.update(jv['header'])
                plaintext = cipher.decrypt_and_verify(jv['ciphertext'],jv['tag'])
                print(plaintext)


if __name__ == "__main__":
    crypto = Crypto()
    crypto.encrypt_db()
    crypto.decrypt_db()

解决方法

文件阅读器随机向salt中添加了额外的node->children[4],所以我在将salt写入文件之前用base64编码,然后在从文件中读取以解密后对其进行解码。 MAC 检查现在不会失败。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。