Después de casi 4 días de trabajo, finalmente conseguí que Libsodium crypto_aead_xchacha20poly1305_ietf_encrypt
funcione y produzca el mismo resultado en JavaScript y PHP .
Pero estoy confundido.
El PHPDoc describe los parámetros como:
* @param string $plaintext Message to be encrypted
* @param string $assocData Authenticated Associated Data (unencrypted)
* @param string $nonce Number to be used only Once
* @param string $key Encryption key
* @return string
Mientras JSDoc solicita estos parámetros:
/**
* @param {string | Uint8Array} message
* @param {string | Uint8Array} additional_data
* @param {string | Uint8Array} secret_nonce
* @param {Uint8Array} public_nonce
* @param {Uint8Array} key
* @param {uint8array} outputFormat
* @returns {Uint8Array}
*/
Mis preguntas:
- Parece que un nonce es un tipo de sal de un tamaño específico que solo se puede usar una vez porque, de lo contrario, pueden ocurrir ataques de repetición. ¿Puedes ayudarme a entender esto más lejos? Wikipedia y otros sitios se complicaron demasiado.
- Para un lego, ¿cómo describiría AEAD y cómo utilizar el parámetro "Datos asociados autenticados (sin cifrar)"?
- En la función PHP (que copié de enlace ), usa el nonce no solo como un nonce sino también como el Los "Datos asociados autenticados" reducen la seguridad en comparación con algún otro enfoque en el que el remitente agregaría algún valor aquí y comunicaría fuera de línea al receptor lo que el receptor debería esperar que sea este valor.
- ¿Por qué la versión de JavaScript acepta parámetros diferentes? JS solicita un secret_nonce separado de public_nonce, y para que los resultados coincidan con la función de PHP, debo proporcionar valores idénticos para secret_nonce y public_nonce. Entonces, ¿cuál es el punto?
P.S. Aquí están las funciones:
JavaScript:
/**
* @param {string} message
* @param {Uint8Array} key
* @returns {Uint8Array}
*/
function encryptAndPrependNonce(message, key) {
let nonce = sodium.randombytes_buf(nonceBytes);
var encrypted = sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(message, nonce, nonce, nonce, key);
var nonce_and_ciphertext = concatTypedArray(Uint8Array, nonce, encrypted);
return nonce_and_ciphertext;
}
PHP:
/**
* @link https://paragonie.com/b/kIqqEWlp3VUOpRD7 (from the 'simpleEncrypt' function)
* @param string $message
* @param string $keyAsBinary
* @return string
*/
public static function encryptAndPrependNonce($message, $keyAsBinary) {
$nonce = random_bytes(self::NONCE_BYTES); // NONCE = Number to be used ONCE, for each message
$encrypted = ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_encrypt($message, $nonce, $nonce, $keyAsBinary);
return $nonce . $encrypted;
}