从python客户端向nodejs发送加密消息

2024-10-02 12:34:37 发布

您现在位置:Python中文网/ 问答频道 /正文

这里我有两个程序。你知道吗

客户端是一个python程序。它需要通过套接字向服务器发送加密消息。它使用pycryptodome包来加密消息。模式为DES。你知道吗

from Crypto.Cipher import DES
from Crypto.Util import Padding
import socket

message=b"abc"
key = b"secret_k"

serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host ='127.0.0.1'
port =8007
serversocket.connect((host,port))

#need to do the padding manually
des = DES.new(key, DES.MODE_ECB)
# ciphered = des.encrypt(message)
ciphered = des.encrypt(Padding.pad(message,8))

plain_msg_withpadding = des.decrypt(ciphered)
# plain_msg = Padding.unpad(plain_withpadding,8)

print ("Deciphered including padding: ", plain_withpadding)
# print ("Decipered without padding: ", plain_msg)


print('msg_to_send', ciphered)
serversocket.send(ciphered)
serversocket.close()

服务器端是一个nodejs程序。它需要解释收到的信息。它使用nodejs的加密包。模式也设置为DES

var net = require('net');
const crypto = require('crypto');

const decipher = crypto.createDecipher('DES-ECB','secret_k');
const local_decipher = crypto.createDecipher('DES-ECB','secret_k');
const cipher = crypto.createCipher('DES-ECB','secret_k')

function encrypt (buf){
    let crypted = Buffer.concat([cipher.update(buf),cipher.final()]);
    return crypted
}

local_message = 'abc'
local_cyphered = encrypt(Buffer.from(local_message));
console.log('cyphered in buffer', local_cyphered);

console.log('local_message decyphered: ', 
local_decipher.update(local_cyphered)+local_decipher.final());


net.createServer(function(socket){

socket.on('data', function(data){
    decipher.setAutoPadding(false);// have to disable auto padding, otherwise final() will raise and error.
    var totalBuffer = Buffer.concat([decipher.update(data),decipher.final()]);

    console.log('decrypted remote message: ',totalBuffer);
    console.log('decrypted remote message in utf-8: ',totalBuffer.toString('utf-8'));

})
}).listen(8007);

console.log("server started at 8007 \n");

当我运行客户端程序时,它会打印结果:

Deciphered including padding:  b'abc\x05\x05\x05\x05\x05'
msg_to_send b'\t\xc3JkP\xca\xd0\xf7'

但在服务器端,结果如下:

cyphered in buffer <Buffer 4f c1 e4 2c fc dd eb 67>
local_message decyphered:  abc
server started at 8007

decrypted remote message:  <Buffer 74 d2 47 08 cd 45 bb 6a>
decrypted remote message in utf-8:  t��E�j

如何使服务器正确解密客户端发送的消息?需要您的专家指导。谢谢您!你知道吗


Tags: logmessagelocalbuffermsgsocketcryptoconsole
2条回答

首先,您需要分解您的问题:消息发送和加密/解密应该分开测试。你知道吗

如果使用createCiphercreateDecipher,则必须提供密码,而不是密钥。对密码进行预处理以创建密钥,但是密钥显然不同于客户端密钥,在尝试解密时会给您带来垃圾。您需要使用createCipherivcreateDecipheriv来使用密钥。然而,上次我检查时,ECB不能很好地使用这些方法。无论如何,使用需要IV的密码模式可能是个好主意;像AES-GCM这样的经过身份验证的模式将是最有益的。你知道吗

setAutoPadding(false)调用应该不是必需的。如果您禁用它,可能是因为解密失败,然后解密结果没有意义。你知道吗

请注意,在节点.js这个包裹很危险。您应该为每个要加密/解密的消息重新创建密码对象。你知道吗

谢谢你,马腾,我已经按照你的要求重写了2个程序提示。现在他们可以有我想要的交流。我知道可能有一些安全问题,但我稍后会改进

from Crypto.Cipher import DES
from Crypto.Util import Padding
import socket

host ='127.0.0.1'
port =8007

greeting=bytes("hello!",encoding="utf-8")
message=bytes("abc这个",encoding="utf-8")
key = b"secret_k"

def ba(byte_data):
  return list(map(hex,bytearray(byte_data))) 

def post_message(msg):
    serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    serversocket.connect((host,port))
    serversocket.send(msg)
    serversocket.close()

#1 test normal connection server should print hello!
post_message(greeting)
print ('plain text', ba(greeting))


#2 test encrypt
padded_msg = Padding.pad(message,8) #need to do the padding manually

des = DES.new(key, DES.MODE_CBC) #using CBC instead of ECB
ciphered = des.encrypt(des.iv+padded_msg)

post_message(ciphered)
print("ciphered : ",ba(ciphered))

在服务器上

var net = require('net');
const crypto = require('crypto');
const key = 'secret_k';

//prepare the cipher with shared key 'secret_k'
const decipher = crypto.createDecipheriv('DES-CBC',key,'iv123456');

var notFirstMessage = false;//just a flag

net.createServer(function(socket){

    socket.on('data', function(data){

        if(notFirstMessage){

            console.log("I will do decipher work\n");
            console.log("encrypted data is: ", data);

            //do the decipher here
            var remote_message = Buffer.concat([decipher.update(data),decipher.final()]);
            console.log("After decipher: ",remote_message.slice(8).toString());//remove the iv
        }else {
            //
            console.log('connection is ok, I got data: ',data.toString());
            notFirstMessage = true;
            console.log("============[Plain Text Connection OK]==============\n")
        }
    });
}).listen(8007);

console.log("server started at 8007 \n");

希望上面的例子可以帮助其他面临同样问题的人。你知道吗

相关问题 更多 >

    热门问题