Итак, я писал простую программу командной строки для шифрования и дешифрования файлов с помощью встроенного в Node модуля crypto
:
if( deciphered_object.multibase_digest != null ){
ciphered_object.multibase_digest = deciphered_object.multibase_digest;
try{
iv_buffer = Crypto.randomBytes(32);
try{
cipher = Crypto.createCipheriv( 'aes-256-ofb', secret_keyobject, iv_buffer );
if( cipher != null && typeof(cipher) === 'object' ){
encrypted_buffer = cipher.update( deciphered_object.deciphered_data_buffer );
encrypted_buffer += cipher.final();
if( encrypted_buffer != null && Buffer.isBuffer(encrypted_buffer) === true ){
try{
ciphered_object.ciphered_data_buffer = Buffer.alloc( (1 + iv_buffer.length + encrypted_buffer.length) );
buffer_offset = ciphered_object.ciphered_data_buffer.writeUInt8( iv_buffer.length, 0 );
buffer_offset += iv_buffer.copy( ciphered_object.ciphered_data_buffer, buffer_offset );
buffer_offset += encrypted_buffer.copy( ciphered_object.ciphered_data_buffer, buffer_offset );
if( buffer_offset === ciphered_object.ciphered_data_buffer.length ){
_return = [0, ciphered_object];
} else{
_return = [-256, 'Error: "buffer_offset" is not equal to "ciphered_object.ciphered_data_buffer.length"'];
}
} catch(error){
_return = [-128, Utility.format('Buffer.alloc threw: %s', error)];
}
} else{
_return = [-64, 'Error: "ciphered_buffer" is either null or not a buffer.'];
}
} else{
_return = [-32, 'Error: "cipher" is either null or not an object.'];
}
} catch(error){
_return = [-16, Utility.format('Crypto.createCipheriv threw: %s', error)];
}
} catch(error){
_return = [-8, Utility.format('Crypto.randomBytes threw: %s', error)];
}
} else{
_return = [-4, 'Error: "deciphered_object.multibase_digest" is either null or undefined.'];
}
Однако, как я обнаружил при тестировании методом грубой силы, очевидно, createCipheriv принимает только длину ключа и IV ровно 16 байтов; против 32 байтов для IV и 4096 байтов для секретного ключа, полученного из Scrypt, я изначально планировал использовать:
password = function_return[1];
function_return = SaltFile.LoadSaltFile();
if( function_return[0] === 0 ){
try{
scrypt_buffer = Crypto.scryptSync( password, function_return[1], 4096 );
secret_keyobject = Crypto.createSecretKey( scrypt_buffer );
if( secret_keyobject != null && typeof(secret_keyobject) === 'object' ){
_return = [0, secret_keyobject];
} else{
_return = [-32, 'Error: "secret_keyobject" is either null or not an object.'];
}
} catch(error){
_return = [-16,Utility.format('Crypto.scryptSync threw: %s', error)];
}
} else{
_return = [function_return[0], 'SaltFile.LoadSaltFile: '+function_return[1]];
}
Хуже всего то, что ни одно из этих ограничений размера не упоминается в документации для createCipheriv: https://nodejs.org/api/crypto.html#crypto_crypto_createcipheriv_algorithm_key_iv_options
Итак, на самом деле меня интересует, почему: почему эти произвольные ограничения? Зачем иметь криптографический пакет, который заставляет использовать смехотворно-слабые ключи, которые любой старый компьютер может перебить силой за считанные минуты? Почему эти оговорки не упомянуты в документации?
Этот 16-байтовый предел ключа кажется мне настолько абсурдным, что делает весь модуль crypto
бесполезным. Можно ли это обойти, используя другой алгоритм или что-то еще? Эти ограничения не имеют никакого смысла ....
Edit:
Ключи AES имеют размер 16, 24 и 32 байта, что составляет 128, 192 и 256 бит соответственно. IV всегда 16 байтов. Это спецификация AES. (@Jww)
Почему ключи RSA обычно 4096 бит (512 байт), но AES ограничен 32 байтами? Почему битовой энтропии 256 достаточно для AES, но не для RSA? Что делает ключи AES менее восприимчивыми к атакам методом перебора, чем ключ RSA?
Если вам нужен 32-байтовый iv, то вам нужно переключиться на Rijndael. (@Jww)
Но я думал, что AES - это Рейндаэль.
Совершенствование базовой симметричной криптографии может помочь вам определить, почему этот вопрос не имеет особого смысла. (@ Люк Джошуа Парк)
Действительно, не полезно; какое чтение по «базовой симметричной криптографии» мне следовало сделать, прежде чем задавать этот вопрос? Очевидно, что я не эксперт, и я не претендовал на это, но в том, что я прочитал о симметричной криптографии, не имеет смысла, что 128-битный ключ достаточно безопасен для AES, но не RSA. Если вы хотите, чтобы я перешел на RTFM, это нормально, но где это руководство, которое я должен был прочитать, прежде чем задавать этот вопрос? Я надеялся, что кто-нибудь сможет объяснить, почему размер ключа в 16 байт защищен, несмотря на то, что это не имеет особого интуитивного смысла.