Шифрование / дешифрование с дополнением RSA / ECB / PKCS1 и дополнением AES / CBC / PKCS5

#encryption #cryptography #cryptojs #jsencrypt

#шифрование #криптография #cryptojs #jsencrypt

Вопрос:

У меня есть API для вызова, где я должен зашифровать свои данные с помощью заполнения RSA / ECB / PKCS1 и AES / CBC / PKCS5PADDING.

 Sample Data: {"KEY":"VALUE"}
  

Шаг.1:

 I have to generate a random number of 16 digit. eg: '1234567890123456'
  

Шаг.2:

 Do RSA/ECB/PKCS1Padding to random number and base64Encode the result. we get "encrypted_key"
  

Шаг.3:

 Concatenate random number amp; data:
DATA = 1234567890123456{"KEY":"VALUE"}
  

Шаг.4:

 Do AES/CBC/PKCS5Padding on DATA (from Step 3) using random number(1234567890123456) as KEY amp; Base64Encoded random number as IV. we get "ENCRYPTED_DATA"
  

Итак, для шага 1 я использую JSEncrypt библиотеку javascript.
для шага 4 я использую CrytoJS.AES.encrypt() функцию. Я почти уверен, что моя функция JSEncrypt работает нормально, поскольку клиент может ее расшифровать, но клиент не может расшифровать мои данные. Я чувствую, что совершаю ошибку при использовании CryptoJS .

Может ли кто-нибудь правильно подсказать мне, как использовать библиотеку.

То, что я делаю, это:

 KEY =  '1234567890123456'
IV  = MTIzNDU2Nzg5MDEyMzQ1Ng==  (result of btoa('1234567890123456') )
DATA = "1234567890123456{"KEY":"VAL"}"

cryptedData = Crypto.AES.encrypt(DATA, KEY, {iv: IV, mode: CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7})
  

Мне сказали использовать PKCS5Padding шифрование AES / CBC (шаг 4), но, похоже, AES это не поддерживает PKCS5Padding , но PKCS7Padding .

Я думаю, что я совершаю ошибку в том, как я передаю KEY amp; IV CryptoJS .

Любая помощь будет принята с благодарностью.

Ответ №1:

Для начала давайте посмотрим, почему вы выполняете упражнение. RSA предназначен для кодирования только ограниченного объема данных. Итак, мы используем «гибридное шифрование», когда данные шифруются с использованием симметричного шифра со случайным ключом, а сам ключ шифруется с использованием RSA

Шифрование работает с двоичными данными, для безопасной передачи двоичных данных данные кодируются в печатную форму (hex или base64)

Шаг.1: Я должен сгенерировать случайное число из 16 цифр

Мы видим 16 цифр 0-9. На самом деле это небезопасно. Генерируя 16 цифр, вы получите ключ 10 ^ 16, что равно приблизительно 2 ^ 53 (если я ошибся в математике, пожалуйста, прокомментируйте).

Вам нужно сгенерировать 16 случайных байтов (цифры 0-256, что дает ключ 2 ^ 128). Это ваш DEK (ключ шифрования данных).

Вы можете закодировать DEK в печатную форму, в шестнадцатеричной кодировке он будет содержать 32 символа.

Шаг.2:

хорошо, теперь вы получаете зашифрованный encoded_encryption_key

Шаг 3, шаг 4

И здесь вы должны понимать, что вы делаете.

  • зашифруйте ДАННЫЕ, используя DEK (не закодированное случайное число в двоичной форме), вы получите encrypted_data. Вы можете закодировать результат в encoded_encrypted_data
  • объедините зашифрованный ключ и зашифрованные данные. Вам решать, кодировать ли его до или после кодирования. Я предлагаю вам выполнить конкатенацию encoded_encryption_key и encoded_encrypted_data с некоторым разделителем, потому что, если длина ключа RSA изменяется, длина encoded_encryption_key также изменяется. Обязательно обсудите с клиентом, какой именно формат ожидается.

Примечания:

  • IV должен иметь длину 16 байт для AES, а для CryptoJS я считаю, что он должен быть шестнадцатеричным, поэтому использование btoa может быть не лучшей идеей. Я считаю, что CryptoJS просто урезает значение до 16 байт, но формально это неверно.
    • Шифр CBC нуждается в какой-то проверке целостности, я предлагаю добавить к результату некоторый HMAC или подпись (в противном случае кто-то может изменить зашифрованный текст, и вы не сможете обнаружить подделку)

но, похоже, что AES поддерживает не PKCS5Padding, а PKCS7Padding.

Действительно, AES поддерживает Pkcs7. Pkcs5 функционально такой же, но определен в 64 блоках. Обозначение все еще используется в Java как наследие DES encryption.

Комментарии:

1. Большое спасибо за подробное объяснение! Я ценю это!