2012-02-07 3 views
1

Почему у меня разные зашифрованные тексты, когда я использовал команды openssl aes и открывал AES apis?Различные зашифрованные тексты, когда я использовал инструменты командной строки OpenSSL AES и API OpenSSL AES?

Я использовал три типа шифрования:

  • Введите) команду OpenSSL линия инструмента
  • типа б) классы в javax.cryto
  • тип C) OpenSSL C API.

Используя тип (a) и (b), я получил тот же зашифрованный текст. Но при использовании (c) у меня есть другой зашифрованный текст.

Я хочу получить одинаковые зашифрованные тексты при использовании метода c и метода a/b. Я думаю, что что-то не так в типе c, но я не могу его найти. Обратите внимание, что я использовал ту же пару KEY, IV в трех вышеупомянутых методах.

Введите:

openssl enc -aes-128-cbc -e -a -in pt.txt -out ct.txt -K 01010101010101010101010101010101 -iv 01010101010101010101010101010101 -p 

Тип б:
Java кода с использованием javax.crypto. Я не буду вставлять код, потому что таким образом я получил тот же зашифрованный текст с типом a.

Тип с: код C с использованием OpenSSL API:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <openssl/aes.h> 

int main(int argc, char** argv) { 

    AES_KEY aes; 
    unsigned char key[AES_BLOCK_SIZE];  // AES_BLOCK_SIZE = 16 
    unsigned char iv[AES_BLOCK_SIZE];  // init vector 
    unsigned char* input_string; 
    unsigned char* encrypt_string; 
    unsigned char* decrypt_string; 
    unsigned int len;  // encrypt length (in multiple of AES_BLOCK_SIZE) 
    unsigned int i; 

    // check usage 
    if (argc != 2) { 
     fprintf(stderr, "%s <plain text>\n", argv[0]); 
     exit(-1); 
    } 

    // set the encryption length 
    len = 0; 
    if (strlen(argv[1])>=AES_BLOCK_SIZE || 
     (strlen(argv[1]) + 1) % AES_BLOCK_SIZE == 0) { 
     len = strlen(argv[1]) + 1; 
    } else { 
     len = ((strlen(argv[1]) + 1)/AES_BLOCK_SIZE + 1) * AES_BLOCK_SIZE; 
    } 

    // set the input string 
    input_string = (unsigned char*)calloc(len, sizeof(unsigned char)); 
    if (input_string == NULL) { 
     fprintf(stderr, "Unable to allocate memory for input_string\n"); 
     exit(-1); 
    } 
    strncpy((char*)input_string, argv[1], strlen(argv[1])); 

    // Generate AES 128-bit key 
    memset(key, 0x01, AES_BLOCK_SIZE); 

    // Set encryption key 
    memset(iv, 0x01, AES_BLOCK_SIZE); 
    if (AES_set_encrypt_key(key, 128, &aes) < 0) { 
     fprintf(stderr, "Unable to set encryption key in AES\n"); 
     exit(-1); 
    } 

    // alloc encrypt_string 
    encrypt_string = (unsigned char*)calloc(len, sizeof(unsigned char));  
    if (encrypt_string == NULL) { 
     fprintf(stderr, "Unable to allocate memory for encrypt_string\n"); 
     exit(-1); 
    } 

    // encrypt (iv will change) 
    AES_cbc_encrypt(input_string, encrypt_string, len, &aes, iv, AES_ENCRYPT); 

    ///////////////////////////////////// 

    // alloc decrypt_string 
    decrypt_string = (unsigned char*)calloc(len, sizeof(unsigned char)); 
    if (decrypt_string == NULL) { 
     fprintf(stderr, "Unable to allocate memory for decrypt_string\n"); 
     exit(-1); 
    } 

    // Set decryption key 
    memset(iv, 0x01, AES_BLOCK_SIZE); 
    if (AES_set_decrypt_key(key, 128, &aes) < 0) { 
     fprintf(stderr, "Unable to set decryption key in AES\n"); 
     exit(-1); 
    } 

    // decrypt 
    AES_cbc_encrypt(encrypt_string, decrypt_string, len, &aes, iv, 
      AES_DECRYPT); 

    // print 
    printf("input_string =%s\n", input_string); 
    printf("encrypted string ="); 
    for (i=0; i<len; ++i) { 
     printf("%u ", encrypt_string[i]);  
    } 
    printf("\n"); 
    printf("decrypted string =%s\n", decrypt_string); 

    return 0; 
} 

Что может быть причиной различных результатов?

+0

Каковы входные и разные выходы? Отличаются ли они полностью или только в последнем блоке? –

+0

Я не мог пропустить мой результат здесь, bcz этот сайт жаловался на формат! Таким образом, я прошел результат на другом веб-сайте, см. Http://topic.csdn.net/u/20120207/16/48183c46-8afd-47d9-a260-7a5eb571f877.html?seed=661539550&r=77510138#r_77510138 Китайский debplop bbs , см. Groupd Four. Благодаря! – user1194299

ответ

2

В коде C, вы, по существу, с использованием дополнения нулями: Вы выделяете область памяти, заполненную нулями (по calloc), а затем скопировать простой текст в этой области, оставив нули в конце нетронутыми.

openssl enc использует различную набивку, отличную от вашего кода на языке C. documentation for openssl enc говорит (акцент мной):

Все блочные шифры обычно используют PKCS # 5 обивки также известную как стандартный блока заполнение: это позволяет рудиментарная целостности или пароль проверка должна быть выполнена. Однако, поскольку вероятность случайных данных, проходящих тест, лучше, чем 1 в 256, это не очень хороший тест.

Кроме того, команда openssl enc использует соль по умолчанию, которая рандомизирует зашифрованный текст. Соль служит аналогичной цели, как вектор инициализации для каждого сообщения (IV). Но вы используете явный IV, поэтому соль не рандомизация зашифрованного текста.

documentation for javax.crypto.Cipher (который я полагаю, вы использовали) говорит:

Преобразование имеет вид:

  • "алгоритм/режим/дополнение" или
  • «алгоритм "

(в последнем случае используются значения по умолчанию для конкретного поставщика для режима и прокладка . Схема). Например, следующий является допустимым преобразованием:

Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding"); 

Так что, если вы просто используете AES или ARS/CBC без указания режима обивки, он использует то, что он находит фитинг, что в вашем случае произошло бы то же самое как то, что использовали OpenSSL (например, PKCS # 5 padding).

Чтобы изменить свою программу на C, вам придется делать то же самое дополнение (по сути, оно заполняет блок числом х байтов, все из которых имеют то же значение, что и это число, при добавлении целого блок, заполненный 16, когда последний блок уже заполнен) - или используйте EVP-функции более высокого уровня, которые должны предоставить вам способ указать режим заполнения для шифрования.

+0

Пауло Эберманн, ты точно прав! Это проблема заполнения! Я совершил эту глупую ошибку! Я вставлю результат на сайт http://topic.csdn.net/u/20120207/16/48183c46-8afd-47d9-a260-7a5eb571f877.html. Я очень ценю вашу помощь. Я бы подружился с u. Моя электронная почта - dungeonsnd # 126.com или dungeonsnd # gmail.com. Еще раз спасибо. – user1194299

+1

Если мой ответ помог вам найти решение, не стесняйтесь отмечать его как * принятый *, щелкнув значок большой галочки рядом с ним. Это * build in * способ сказать «спасибо» на этом сайте. –

 Смежные вопросы

  • Нет связанных вопросов^_^