Estoy tratando de cifrar una cadena en el servidor golang, tengo una utilidad de cifrado 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 }y después de eso estoy tratando de hacer algo así
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 } pero para esta clave y texto cifrado recibo este error en el sitio aes de cifrado/descifrado 
js func para decodificar tampoco funciona
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) }simplemente no imprime nada
El código Go se rellena con valores 0x30 si el tamaño del texto sin formato ( cypherText , un término engañoso por cierto) no es un múltiplo entero del tamaño del bloque (16 bytes para AES). Como clave se utiliza la codificación UTF-8 de la codificación hexadecimal de los primeros 16 bytes del valor SHA256 de la contraseña ( word ). El texto cifrado está codificado en hexadecimal.
El descifrado con la herramienta en línea falla porque la herramienta en línea usa relleno PKCS#7 y el texto cifrado está decodificado en Base64. Para que el descifrado sea posible, el relleno predeterminado PKCS#7 debe estar deshabilitado y el texto cifrado debe decodificarse en hexadecimal, consulte, por ejemplo, CyberChef .
El descifrado con el código JavaScript falla porque CryptoJS usa el relleno PKCS#7 de forma predeterminada, la clave se descodifica en hexadecimal y el texto cifrado no se pasa como objeto CipherParams . Para que el descifrado sea posible, el relleno predeterminado PKCS#7 debe estar deshabilitado, la clave debe estar codificada en UTF-8 y el texto cifrado debe pasarse como un objeto 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> da como datos decodificados UTF-8 descifrados: деньBvFGlrXeWCnPTwFC00000000 .
Seguridad: ECB no utiliza un IV y por lo tanto es inseguro. Hoy en día, se aplica el cifrado autenticado (p. ej., GCM), pero al menos un modo con un IV (p. ej., CBC).
Además, es inseguro usar un resumen como función de derivación clave (KDF). Hay funciones dedicadas para esto (por ejemplo, Argon2 o PBKDF2). Además, la cadena de bytes del KDF debe usarse directamente y no la codificación UTF-8 de la codificación hexadecimal, lo que reduce la seguridad.
El relleno 0x30 aplicado generalmente no es confiable. Más fiable es, por ejemplo, el relleno PKCS#7.