使用python加密解密pushbullet通知时出现InvalidTag错误

使用python加密解密pushbullet通知时出现InvalidTag错误,python,python-3.x,encryption,aes-gcm,pushbullet,Python,Python 3.x,Encryption,Aes Gcm,Pushbullet,我试图在python3中实现对pushbullet临时消息的端到端加密支持 我正在使用,但我在解密时得到一个InvalidTag-异常。我已经仔细检查了钥匙、iv和标签,但我不知道哪里出了问题 密钥的派生方式如下: salt = user_ident.encode() pw = password.encode() kdf = PBKDF2HMAC( algorithm=hashes.SHA256(), length=32

我试图在python3中实现对pushbullet临时消息的端到端加密支持

我正在使用,但我在解密时得到一个
InvalidTag
-异常。我已经仔细检查了钥匙、iv和标签,但我不知道哪里出了问题

密钥的派生方式如下:

    salt = user_ident.encode()
    pw = password.encode()

    kdf = PBKDF2HMAC(
            algorithm=hashes.SHA256(), 
            length=32,
            salt=salt,
            iterations=30000,
            backend=backend)

    dkey = kdf.derive(pw)
b'1' + encryptor.tag + iv + ciphertxt
然后它作为Base64编码字符串存储在一个密钥环中,但我在加密时仔细检查了是否得到了正确的字节字符串(也通过在REPL中手动执行)

解密:

ciphertxt = a2b_base64(msg['ciphertext'])
version = ciphertxt[0:1]
tag = ciphertxt[1:17]
iv = ciphertxt[17:29]
enc_msg = ciphertxt[29:]

# Construct an AES-GCM Cipher object
decryptor = Cipher(
    algorithms.AES(self.dkey_),
    modes.GCM(iv, tag),
    backend=backend
).decryptor()

cleartxt = decryptor.update(enc_msg) + decryptor.finalize()
所有变量都是字节字符串,这里是python加密的基础

澄清: 我尝试了我自己的方法来加密并成功解密一些文本。但是,当我在手机和客户端上激活Pushbullet e2e加密并收到通知时,我得到了上述错误

加密方法按如下方式组合加密消息:

    salt = user_ident.encode()
    pw = password.encode()

    kdf = PBKDF2HMAC(
            algorithm=hashes.SHA256(), 
            length=32,
            salt=salt,
            iterations=30000,
            backend=backend)

    dkey = kdf.derive(pw)
b'1' + encryptor.tag + iv + ciphertxt
我能破译它。无法使用接收到的消息中的标记


有什么想法吗/

我最近在文档页面上添加了一些交互式javascript内容:

我发现调试这样一个问题的最好方法是单独测试每个部分,并确保为给定的输入获得正确的输出

在您的例子中,我认为您应该创建一个不变的密钥、IV和消息,并确保您的库生成与该示例中的javascript代码相同的加密消息。这可能是这样的:

// convert key from base64 to binary
var key = atob("1sW28zp7CWv5TtGjlQpDHHG4Cbr9v36fG5o4f74LsKg=");
var initialization_vector = atob("O2QAL8AYQB+qbre8"); // 96-bit
var message = "meow!";

var cipher = forge.cipher.createCipher('AES-GCM', key);
cipher.start({"iv": initialization_vector});
cipher.update(forge.util.createBuffer(forge.util.encodeUtf8(message)));
cipher.finish();

var tag = cipher.mode.tag.getBytes();
console.log("tag", btoa(tag));
var encrypted_message = cipher.output.getBytes();
console.log("encrypted_message", btoa(encrypted_message));
其输出为:

tag OBA7UU/Rd9j0Zn+9korAyQ== 
encrypted_message 7YS1aTE= 
一旦python加密与此匹配,您应该确保解密部分工作正常

var key = atob("1sW28zp7CWv5TtGjlQpDHHG4Cbr9v36fG5o4f74LsKg=")
var tag = atob("OBA7UU/Rd9j0Zn+9korAyQ==")
var initialization_vector = atob("O2QAL8AYQB+qbre8"); // 96 bits
var encrypted_message = atob("7YS1aTE=");

var decipher = forge.cipher.createDecipher('AES-GCM', key);
decipher.start({
    'iv': initialization_vector,
    'tag': tag
});
decipher.update(forge.util.createBuffer(encrypted_message));
decipher.finish();

var message = decipher.output.toString('utf8');
console.log("message:", message);
其中应打印:

message: meow! 

我对这个特定的python库没有任何经验,但是如果您使用这种调试技术,您应该能够缩小问题所在的范围。

Ty。我看过你的(很棒的)文档,我也试过(我想是多次)。我可以运行您的完整示例。若我使用收到的消息中的真正密钥、iv和标记,我也可以加密和解密。但是我无法用消息中的标记解密原始消息。虽然这可能是编码问题,但由于我可以使用标记进行加密……仔细检查您提到的python库,您会发现一个无效标记错误,原因至少如下:无效密钥、无效标记、无效iv、无效加密消息。似乎其中一个是不正确的。你能仔细检查每个文档的字节吗?确保它们看起来有效,位长度正确,并且当你使用交互式文档时,你得到的密钥与你用来解密的文档相同?我想知道“交互式”部分。我没有看到run按钮(),我在js控制台上得到一个错误:“TypeError:code未定义--docs.pushbullet.com:2022:10”。我的JS不好,但不是有一些';'或者,“缺失?键len=32,iv len=12,标记len=16。我从JSON数据中获取整个“密文”字段,并将其从base64转换为二进制,对吗?”因为里面有很多“\n”。消息的前29个字节(字节)是(在base64中):b'MVQifJKyMxY95rolWSG/n59owqtjqh5h5e2lmp804=\n'密钥是b'p7xrLWLPqC8QW0J4/RgQ9XCJP19TdTjki9y6tiFCNx0=\n'密码只是用于测试的假“Foo”,但我不想发布整个消息,因为它包含我的电子邮件地址和名称。不知道我还能如何生成通知。