2

Java と C で暗号化された同じ平文が同じ暗号文を生成しないのはなぜだろうか。DESアルゴリズムについて私が気づいた

入力text = "text", key = "test"

C 暗号文len = 24 Java が暗号文を生成するlen = 8

256Bit AES の場合、同様の違いに気付きました
C 暗号文len = 32 Java が暗号文を生成しますlen = 16

ここに私の「C」コードがあります

char* enc(const char* text, const char* keyStr)
{
    EVP_CIPHER_CTX ctx;
    unsigned char key[32] = {0};
    unsigned char iv[16] = {0};
    unsigned char in[16] = {0};
    unsigned char out[32]; /* at least one block longer than in[] */
    memset(out, 0, 32);
    int outlen1, outlen2;

    memcpy(in, text, strlen(text));
    memcpy(key, keyStr, strlen(keyStr));

    EVP_EncryptInit(&ctx, EVP_aes_256_cbc(), key, iv);    
    EVP_EncryptUpdate(&ctx, out, &outlen1, in, sizeof(in));
    EVP_EncryptFinal(&ctx, out + outlen1, &outlen2);

    char* ret  = (char*)malloc(outlen1 + outlen2+1);
    memset(ret, 0, outlen1 + outlen2+1);
    memcpy(ret, out, outlen1 + outlen2);

    EVP_CIPHER_CTX_cleanup(&ctx);

    return ret;
}

ここに「Java」コードがあります

public static byte[] enc(byte[] input, byte[] keyStr){
        byte[] output = null;

        try {           
            byte[] newKey = getByteArrays(keyStr, 0, 32);
            SecretKey secretKey = new SecretKeySpec(newKey, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");  
            //Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
            String ivStr = "";
            byte[] ivKey = getByteArrays(ivStr.getBytes("UTF-8"), 0, 16);
            IvParameterSpec ips = new IvParameterSpec(ivKey);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, ips, null);         
            output = cipher.doFinal(input);

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }       
        return output;
    }

C を使用して暗号化されたエントリのリストがあり、それらのエントリを Java で復号化したいと考えています。

更新
後の更新により、「C」と「JAVA」の両方で同じ長さを取得するのに役立ちました

EVP_EncryptUpdate(&ctx, out, &outlen1, in, strlen(テキスト));

「C」と「JAVA」によって返される暗号文が同じテキストとキーに対して異なるのはなぜだろうか、私はそれらが同じであることを期待しています

4

1 に答える 1

1

C コードが 32 バイトの暗号文を出力する理由は、入力文字列を暗号化関数に渡す前にゼロを埋め込んでいるためです。

この行で:

EVP_EncryptUpdate(&ctx, out, &outlen1, in, sizeof(in));

関数は、データにゼロを埋め込んだことを認識しません。は 16なのでsizeof(in)、平文の長さは 16 になります。また、PKCS5 パディング (および AES) を使用すると、16 バイトが 32 バイトにパディングされます。

Java コードでは、入力を手動でパディングせず、暗号化関数に直接渡しました。したがって、暗号化関数は平文のサイズを 4 バイトと見なし、PKCS5 パディングで 16 にパディングします。

したがって、ソリューションは簡単です。C コードに入力を手動で埋め込まないでください。平文を に直接渡すだけEVP_EncryptUpdateです。パディングされていないプレーンテキストを処理するように設計されています。

于 2013-09-17T16:32:49.890 に答える