首頁 > 後端開發 > Golang > 主體

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

PHPz
發布: 2024-02-12 13:57:13
轉載
544 人瀏覽過

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

問題內容

我正在嘗試將一個go 程式(https://github.com/mckael/samtv)移植到node.js,該程式可以透過“smartview”api 控制三星電視

程式中有一個「aes 加密」功能,我在移植到節點時遇到問題。

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
}
登入後複製

我現在面臨的問題是,我不知道使用了什麼algorythim,或者我需要在我的node.js函數中指定「初始向量」來自哪裡:

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;
});
登入後複製

我可以用 crypto.createcipher(...) 來代替嗎?但它已被棄用,而且感覺填充的東西很重要。

我對加密一無所知。 歡迎任何提示。

注意:在go函數中,s.sessionkey與node.js中的session_key = "59e8ca4b09f2a19ab5421cf55d604c7c"的值相同

解決方法

go 程式碼在ecb 模式下套用aes 並使用pkcs#7 填入。 aes 變體隱含源自於金鑰大小,例如aes-128 用於 16 位元組金鑰。密文回傳為 []byte

在 nodejs 程式碼中,明確指定了 aes 變體以及模式,例如aes-128-ecb。 ecb模式不套用iv,因此必須在createcipheriv()中指定為null。使用填入 pkcs#7(預設)。密文可以回傳為 buffer,它最接近 []byte

發布的金鑰 59e8ca4b09f2a19ab5421cf55d604c7c 看起來像是十六進位編碼的金鑰,它是十六進位解碼的 16 位元組大,因此對應於 aes-128。十六進位解碼可以在 go 中使用 encoding/hex 套件來實現,例如與 hex.decodestring("59e8ca4b09f2a19ab5421cf55d604c7c")

在 ecb 模式下使用 aes-128(16 位元組金鑰)和 pkcs#7 填入的 nodejs 程式碼範例:

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
登入後複製

go 程式碼使用相同的金鑰(十六進位解碼)和明文以及密文的 base64 編碼給出相同的結果。

為了完整性:金鑰也可以採用utf-8 編碼,然後產生32 位元組金鑰,例如go 程式碼中的key := []byte("59e8ca4b09f2a19ab5421cf55d604c7c")const session_key = buffer.from("59e8ca4b09f2a19ab5421cf55d604c7c", "utf-8") nodejs 程式碼。在 nodejs 程式碼中,也必須套用 aes-256-ecb。最終,關鍵規範必須提供有關使用哪種編碼的資訊。

請注意,ecb 模式不安全。如今,通常使用經過身份驗證的加密,例如透過 gcm 模式。

以上是將 AES 加密功能移植到 node.js的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!