Maison >développement back-end >Golang >Portage de la fonctionnalité de chiffrement AES vers node.js

Portage de la fonctionnalité de chiffrement AES vers node.js

PHPz
PHPzavant
2024-02-12 13:57:13594parcourir

将 AES 加密功能移植到 node.js

Contenu de la question

J'essaie de porter un programme go (https://github.com/mckael/samtv) vers node.js qui peut contrôler un téléviseur Samsung via l'API "smartview"

Il existe une fonctionnalité de "cryptage aes" dans le programme que j'ai du mal à porter sur le nœud.

func (s *smartviewsession) aesencrypt(plaindata []byte) ([]byte, error) {
    //logrus.debugf("aesencrypt(%#v) : '%s'", plaindata, string(plaindata))
    //logrus.debugf("session id:  %d", s.sessionid)
    //logrus.debugf("session key: '%x'\n  %v", string(s.sessionkey), s.sessionkey)

    // create cipher block
    block, err := aes.newcipher(s.sessionkey)
    if err != nil {
        return nil, err
    }

    bs := block.blocksize()
    //logrus.debugf("block size: %d", bs)

    // add padding
    padding := bs - len(plaindata)%bs
    padtext := bytes.repeat([]byte{byte(padding)}, padding)
    //logrus.debugf("padding: %d byte(s)", padding)
    plaindata = append(plaindata, padtext...)

    // encrypt
    ciphertext := make([]byte, len(plaindata))
    for cipherrange := ciphertext; len(plaindata) > 0; {
        block.encrypt(cipherrange, plaindata[:bs])
        plaindata = plaindata[bs:]
        cipherrange = cipherrange[bs:]
    }

    //logrus.debugf("ciphertext: %#v", ciphertext)
    return ciphertext, nil
}

Le problème auquel je suis confronté maintenant est que je ne sais pas quel algorithme utiliser ni d'où je dois spécifier dans ma fonction node.js d'où vient le "vecteur initial":

const SESSION_KEY = "59e8ca4b09f2a19ab5421cf55d604c7c";

var aesEncrypt = ((val, algo = "aes-256-cbc") => {
    let cipher = crypto.createCipheriv(algo, SESSION_KEY, IV);
    let encrypted = cipher.update(val, 'utf8', 'base64');
    encrypted += cipher.final('base64');
    return encrypted;
});

Puis-je utiliser crypto.createcipher(...) à la place ? Mais il est obsolète et il semble que les éléments de remplissage soient importants.

Je ne connais rien au cryptage. Tous les conseils sont les bienvenus.

Remarque : Dans la fonction go, la valeur de s.sessionkey est la même que la valeur de session_key = "59e8ca4b09f2a19ab5421cf55d604c7c" dans node.jss.sessionkey与node.js中的session_key = "59e8ca4b09f2a19ab5421cf55d604c7c"的值相同

解决方法

go 代码在 ecb 模式下应用 aes 并使用 pkcs#7 填充。 aes 变体隐式源自密钥大小,例如aes-128 用于 16 字节密钥。密文返回为 []byte

Solution

aes-128-ecb。 ecb模式不应用iv,因此必须在createcipheriv()中指定为null。使用填充 pkcs#7(默认)。密文可以返回为 buffer,它最接近 []bytego code en mode ecb Appliquez aes et utilisez le remplissage pkcs#7. La variante aes est implicite dérivée de la taille de la clé, par exemple aes-128 pour les clés de 16 octets. Le texte chiffré est renvoyé sous la forme []byte.

Dans le code nodejs, les variantes et modes aes sont explicitement spécifiés, comme 59e8ca4b09f2a19ab5421cf55d604c7c 看起来像一个十六进制编码的密钥,它是十六进制解码的 16 字节大,因此对应于 aes-128。十六进制解码可以在 go 中使用 encoding/hex 包来实现,例如与 hex.decodestring("59e8ca4b09f2a19ab5421cf55d604c7c").

Clé publiée

.

Exemple de code Nodejs utilisant aes-128 (clé de 16 octets) et remplissage pkcs#7 en mode ecb :

var crypto = require('crypto');

const SESSION_KEY = Buffer.from("59e8ca4b09f2a19ab5421cf55d604c7c", "hex");

var aesEncrypt = ((val, algo = "aes-128-ecb") => {
    let cipher = crypto.createCipheriv(algo, SESSION_KEY, null);
    return Buffer.concat([cipher.update(val, 'utf8'), cipher.final()]);
});

var ciphertext = aesEncrypt("The quick brown fox jumps over the lazy dog");
console.log(ciphertext.toString('base64')); // T/uQforseVFkY93mqwpwCGVVnEFDTT5Gle8a8XUxCfOXCfYUo3uCJ/nwzCIJ9xqf
key := []byte("59e8ca4b09f2a19ab5421cf55d604c7c")const session_key = buffer.from("59e8ca4b09f2a19ab5421cf55d604c7c", "utf-8") nodejs 代码。在 nodejs 代码中,还必须应用 aes-256-ecbLe code go donne le même résultat en utilisant la même clé (décodage hexadécimal) et le même encodage base64 du texte brut et du texte chiffré.

Pour être complet : la clé peut également être encodée en utf-8 puis générer une clé de 32 octets, comme

dans le code go. En fin de compte, la spécification de la clé doit fournir des informations sur le codage à utiliser. 🎜 🎜Veuillez noter que le mode ecb n'est pas sécurisé. De nos jours, il est courant d'utiliser un cryptage authentifié, par exemple via le mode gcm. 🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer