当前位置: 首页 > 知识库问答 >
问题:

使用python3和node js进行加密和解密

牧熙云
2023-03-14

我正在尝试创建一个多平台的加密-解密机制,到目前为止,我已经能够用python进行加密,用C进行解密,反之亦然,现在我正在尝试使用python脚本和node js脚本进行同样的操作。我能够在node js中加密字符串,并在python中解密,但在node中使用python的加密消息进行解密是不可能的。这里是python代码:

from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto import Random
from base64 import b64decode
from base64 import b64encode
import json
import random

#iv= get_random_bytes(16)
key=b"aaaaaaaaaaaaaaaa"
iv= b"aaaaaaaaaaaaaaaa"
value = "Hello World"
strValue= str.encode(value)
data =strValue

#Encryption
data = b64encode(data)
pad =data + b"\0" * (AES.block_size - len(data) % AES.block_size)
cipher = AES.new(key, AES.MODE_CBC, iv)
ciphertext= cipher.encrypt(pad)
print (type(ciphertext))

print(b64encode(ciphertext).decode("utf-8"))

# Decryption
cipher = AES.new(key, AES.MODE_CBC, iv)
data = cipher.decrypt(ciphertext)
print(b64decode(data))

以下是Nodejs代码:

const crypto = require('crypto'); 

var iv = Buffer.from('aaaaaaaaaaaaaaaa')
var key =  Buffer.from('aaaaaaaaaaaaaaaa')
var cipher = crypto.createCipheriv('aes-128-cbc', key, iv);

let enc= cipher.update( "Hello World");
console.log(typeof (enc))
enc += cipher.final('base64');

console.log("enc is :",enc)



var decipher = crypto.createDecipheriv('aes-128-cbc', key,iv);
let decrypted = decipher.update(enc, 'base64');
decrypted += decipher.final('utf8'); 
console.log("plain text is :",decrypted)

我的节点部分来自:AES-加密加密(node js)/Pycrypto解密(python)我得到错误:0606065064:数字信封例程:EVP\u decrypt final\u ex:bad decrypt非常感谢您的帮助!如果有更好的节点js实现方法,请告诉我。

共有1个答案

西门飞星
2023-03-14

在Python代码中,明文是加密前编码的Base64,在NodeJS代码中不是。此外,Python代码应用了自定义零填充,NodeJS代码是默认的PKCS7填充。

为了使NodeJS代码提供与Python代码相同的密文,必须在加密之前对明文进行Base64编码。此外,必须禁用默认的PKCS7填充,并且必须应用Python代码的零填充变量。由于PyCryptodome不支持零填充,因此需要自定义实现。

一种可能的NodeJS实现可以是:

const crypto = require('crypto') 
const buffertrim = require('buffertrim') 

function toB64padded(plaintext, blocksize){
    var bufPlaintext = Buffer.from(plaintext, 'utf8')
    var bufPlaintextB64 = Buffer.from(bufPlaintext.toString('base64'), 'utf8')      // Base64 encoding
    var bufPadding = Buffer.alloc(blocksize - bufPlaintextB64.length % blocksize)
    return Buffer.concat([bufPlaintextB64, bufPadding])                             // Zero padding
}

var iv = Buffer.from('aaaaaaaaaaaaaaaa')                                            // Static IV only for testing purposes
var key =  Buffer.from('aaaaaaaaaaaaaaaa')

// Encryption
var plaintext = "The quick brown fox jumps over the lazy dog"
var bufPlaintextB64padded = toB64padded(plaintext, 16)                              // Base64 encoding and Zero padding
var cipher = crypto.createCipheriv('aes-128-cbc', key, iv)
cipher.setAutoPadding(false)                                                        // Disable PKCS7 padding

var ciphertextB64 = cipher.update(bufPlaintextB64padded, '', 'base64')              // Encryption, Base64 encoding of ciphertext 
ciphertextB64 += cipher.final('base64')
console.log("ciphertext is:", ciphertextB64)  

// Decryption
var decipher = crypto.createDecipheriv('aes-128-cbc', key, iv)
decipher.setAutoPadding(false)                                                      // Disable PKCS7 (un-) padding

var bufPlaintextB64padded = Buffer.concat([                                         // Base64 decoding of ciphertext, decryption
    decipher.update(ciphertextB64, 'base64'), 
    decipher.final()
]);                                                                                 
var bufPlaintextB64 = buffertrim.trimEnd(bufPlaintextB64padded)                     // Unpadding (unreliable)
var bufPlaintext = Buffer.from(bufPlaintextB64.toString('utf8'), 'base64')          // Base64 decoding
console.log("plaintext is:", bufPlaintext.toString('utf8'))

例如,用上面的Python代码和NodeJS代码对快速棕色狐狸跳过懒狗的明文进行加密。这两种代码使用已发布的密钥和IV生成相同的密文,即:

IETFUbiTGsKFZWLgjjP5RrKPX+GeVon1Kuy38bPdKXwqUJWUGWMJ9MOL9gEAsF+1U/N0Juwzu24Dju4UMwdZaA== 

这意味着可以用一种代码加密,用另一种代码解密。

请注意,加密前不必对明文进行Base64编码。此外,零填充是一种不可靠的填充,最好用PKCS7填充代替。PyCryptodome支持PKCS7填充加密。Util。填充模块,因此填充不需要自定义实现。如前所述,NodeJS的加密模块默认使用PKCS7填充。

此外,出于安全原因,每个加密必须使用随机IV。静脉注射不是秘密的,通常与密文相连。在Python代码中实现了IV的随机生成(但是注释掉了,可能是为了测试目的)。然而,串联部分缺失。在NodeJS代码中,为了与Python代码兼容,两者都被省略了。

 类似资料:
  • 问题内容: 我正在尝试在Python中加密某些内容,并在nodejs应用程序中对其进行解密。 我正在努力使这两个AES实现一起工作。这是我的位置。 在节点中: 产生输出: 在python中 这产生输出 显然,它们非常接近,但是node似乎在用某些内容填充输出。有什么想法可以使两者互操作吗? 问题答案: 好的,我已经弄清楚了,节点使用OpenSSL,后者使用PKCS5进行填充。PyCrypto不处理

  • 问题内容: 这是我正在做的事情,可能看起来有些笨拙,但是可以帮助您解决该问题。我得到一个。阅读几乎所有相关主题,但找不到合适的解决方案。我是加密解密程序设计的新手,需要在我的Java应用程序之一中实现它。 谢谢..这就是代码的样子.... 问题答案: 在这里,您需要了解的是密文可能包含不可打印的字符。因此,当您使用readLine()时,它可能不会为您提供文件中的所有字节。 同样,它并没有给您您认

  • null 下面是我当前的代码: 以下是我的结果: 原文: 正如您所看到的,加密中缺少几个字符,这也影响了解密。缺的是2号线的v和3号线的v 你知道为什么吗?

  • 问题内容: 我只想确认我对AES如何工作的理解。 如果company#1正在加密数据,并将此数据发送到company#2进行解密,则假定其中一个使用C#,另一个使用Java。 只要双方都使用相同的共享密钥,双方是否应该在设置/配置方面达成共识,以确保数据正确地加密和解密? 问题答案: 两者都有很多共识: 共享密钥 多久了?(是否需要填充键盘?) 实际的密钥是从另一个密钥或密码派生而来的吗? 使用了

  • 我将AES与salt和IV一起用于加密和解密一个唯一的ID,但它给出了javax。加密。解密时出现BadPaddingException。 每次解密数据时给出的完整错误堆栈跟踪 加密方法- 解密方法 我是JCA的新手。

  • 问题内容: 我正在使用Java应用程序,该应用程序要求我使用从不同字符串生成的两个密钥进行加密和解密。一个字符串来自用户,另一个是主密钥。我上网查看了有关它的一些参考资料。我真的很想知道如何实现此目标。我将展示我现在拥有的。 因此,从代码中可以看到,我使用了其他stackoverflow帖子中的一些代码,并对其进行了一些修改。我只是不知道如何从2个字符串生成2个密钥,以及从哪里可以获取用于解密的S