[英]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.