簡體   English   中英

將 go AES 加密函數移植到 node.js

[英]Port go AES Encrypt function to node.js

我正在嘗試將一個可以通過“SmartView”API 控制三星電視的程序( https://github.com/McKael/samtv )移植到 node.js

程序中有一個“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 代碼在帶有 PKCS#7 填充的 ECB 模式下應用 AES。 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 模式和 PKCS#7 填充中使用 AES-128(16 字節密鑰)的 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 模式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM