[英]encode string aes-128 ecb in golang and decrypt in js
我正在嘗試在 golang 服務器上加密字符串,我有一個 aes-128 加密工具
func EncryptAES(key []byte, plaintext string) (string, error) {
// create cipher
c, err := aes.NewCipher(key)
if err != nil {
return "", err
}
// allocate space for ciphered data
out := make([]byte, len(plaintext))
for i := 1; i <= len(plaintext)/16; i++ {
tempBuf := make([]byte, 16)
offset := (i - 1) * 16
limit := offset + 16
// encrypt
c.Encrypt(tempBuf, []byte(plaintext[offset:limit]))
for j := 0; j < len(tempBuf); j++ {
out[offset+j] = tempBuf[j]
}
}
// return hex string
return hex.EncodeToString(out), nil
}
之后我試圖做類似的事情
hasher := sha256.New()
hasher.Write([]byte(word))
sha := hasher.Sum(nil)
cypherText := word + userSessionKey
for len([]byte(cypherText))%16 != 0 {
cypherText += "0"
}
sha128 := sha[:len(sha)/2]
captchaKey, err := utils.EncryptAES([]byte(hex.EncodeToString(sha128)), cypherText)
if err != nil {
SendErrorResponse(ctx, fasthttp.StatusInternalServerError, []byte("error generating aes session key "+err.Error()))
return
}
但是對於這個密鑰和密文,我在加密/解密 aes 站點上收到此錯誤
用於解碼的js func也不起作用
async function decryptAES128(key, cipherText){
let hash = CryptoJS.SHA256(key).toString();
hash = hash.substring(0, hash.length/2);
console.log(hash);
console.log(cipherText)
const bytes = await CryptoJS.AES.decrypt(CryptoJS.enc.Hex.parse(cipherText), CryptoJS.enc.Hex.parse(hash), { mode: CryptoJS.mode.ECB });
return CryptoJS.enc.Utf8.stringify(bytes.words)
}
什么都不打印
如果明文的大小( cypherText
,順便說一句具有誤導性)不是塊大小的整數倍(AES 為 16 字節),則 Go 代碼填充 0x30 值。 作為密鑰,使用密碼 ( word
) 的 SHA256 值的前 16 個字節的十六進制編碼的 UTF-8 編碼。 密文是十六進制編碼的。
使用 在線工具解密失敗,因為在線工具使用 PKCS#7 填充並且密文是 Base64 解碼的。 為了使解密成為可能,必須禁用默認的 PKCS#7 填充,並且必須對密文進行十六進制解碼,參見例如CyberChef 。
使用 JavaScript 代碼解密失敗,因為 CryptoJS 默認使用 PKCS#7 填充,密鑰是十六進制解碼的,並且密文沒有作為CipherParams
對象傳遞。 為了使解密成為可能,必須禁用默認的 PKCS#7 填充,密鑰必須是 UTF-8 編碼,並且密文必須作為CipherParams
對象傳遞:
var password = 'день'; var key = CryptoJS.SHA256(password).toString(); key = key.substring(0, key.length/2); var ciphertext = '46ef70c1193fa29024595964a0eb0157c4e6602da6c1429f8a2b81146f79e798' var decrypted = CryptoJS.AES.decrypt( {ciphertext: CryptoJS.enc.Hex.parse(ciphertext)}, // Fix 1: pass a CipherParams object CryptoJS.enc.Utf8.parse(key), // Fix2: UTF-8 encode the key { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding }); // Fix 3: disable padding console.log(decrypted.toString(CryptoJS.enc.Utf8));
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
給出解密的 UTF-8 解碼數據: деньBvFGlrXeWCnPTwFC00000000
。
安全性:歐洲央行不使用 IV,因此不安全。 如今,應用了經過身份驗證的加密(例如 GCM),但至少是一種帶有 IV 的模式(例如 CBC)。
此外,使用摘要作為密鑰派生函數(KDF)是不安全的。 為此有專門的功能(例如 Argon2 或 PBKDF2)。 另外,應該直接使用 KDF 的字節串,而不是 hex 編碼的 UTF-8 編碼,這樣會降低安全性。
應用的 0x30 填充通常是不可靠的。 更可靠的是例如 PKCS#7 填充。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.