【问题标题】:Output AES/ECB/PKCS7 in c and java is not samec和java中的输出AES/ECB/PKCS7不一样
【发布时间】:2013-12-02 05:11:57
【问题描述】:

您好,我使用 AES/ECB/PKCS7 模式进行加密,单独在 c&java 中,加密和解密工作正常。但是c中的加密数据和java中的加密数据是不一样的……

我用 C 语言和 java 发布我的代码。我需要 c 中的加密和 java 中的解密。请帮助我 aes/ecb/pkcs7 的 c 代码是否正确??.. 我正在使用 openssl

C 代码:

int Secure_encrypt(unsigned char *in, int inlen, unsigned char *out,int *outlen)
{
    int tmplen;
    // Key is 256 and is fixed.
    unsigned char key[256] =
    {   0x21,0x0a,0x03,0x23,0x45,0x29,0x78,0x12,0x35,0x45,0x67,0x78,0x21,0x13,
        0x34,0x56,0x67,0x45,0x12,0x89,0x38,0x0e,0xa0,0x15,0x21,
        0x0a,0x03,0x23,0x45,0x0b,0x15,0x0c
    };
    unsigned char *iv=0;
    EVP_CIPHER_CTX x;
    EVP_CIPHER_CTX_init(&x);
    EVP_CIPHER_CTX_set_padding(&x,1); // 1- padding, 0 - No Padding
    if (!EVP_EncryptInit_ex(&x, EVP_aes_256_ecb(), 0, key, iv))
    {
        //printf("\n ERROR!! \n");
        return -1;
    }
    if (!EVP_EncryptUpdate(&x, out, outlen,(const unsigned char*) in, inlen))
    {
        //printf("\n ERROR!! \n");
        return -2;
    }
    if (!EVP_EncryptFinal_ex(&x,out + *outlen,&tmplen)) {
        //printf("\n ERROR!! \n");
        return -3;
    }
    *outlen += tmplen;
#ifdef DEBUG
    printf ("AES encrypted data %d len\n", *outlen);
    print_data (out, *outlen);
#endif
    EVP_CIPHER_CTX_cleanup(&x);
    return 0;

}



/*AES DECRYPTION */
AES Decryption



int Secure_decrypt(unsigned char *in, int inlen, unsigned char *out,int *outlen)
{
    int tmplen;
    unsigned char *iv=0;
    unsigned char key[256]
    //AES/ECB/PKCS7 Padding
    EVP_CIPHER_CTX x;
    EVP_CIPHER_CTX_init(&x);
    EVP_CIPHER_CTX_set_padding(&x,1); // 1- padding, 0 - No Padding
    if (!EVP_DecryptInit_ex(&x, EVP_aes_256_ecb(), 0, key, iv)) {
        //printf("\n ERROR!! \n");
        return -1;
    }
    if (!EVP_DecryptUpdate(&x, out, outlen,(const unsigned char*) in, inlen))
    {
        //printf("\n ERROR!! \n");
        return -2;
    }
    if (!EVP_DecryptFinal_ex(&x,out + *outlen,&tmplen)) {
        //printf("\n ERROR!! \n");
        return -3;
    }
    *outlen += tmplen;

#ifdef DEBUG
    printf ("AES encrypted data %d len \n", *outlen);
    print_data (out, *outlen);
#endif
    EVP_CIPHER_CTX_cleanup(&x);
    return 0;
}

Java 代码:

import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class doThis {

    public static void main(String[] args) {
        Security.addProvider(new BouncyCastleProvider());
        String strDataToEncrypt = "Testing Encryption";
        byte[] byteDataToTransmit = strDataToEncrypt.getBytes();
        //41 6E 6B 61 72 61 6F 20 49 74 74 61 64 69
        //byte[] byteDataToTransmit = new byte []
        {
            0x41,0x6E,0x6B,0x61,0x72,0x61,0x6F,0x20,0x49,0x74,0x74,0x61,0x64,0x69
        };
        try {

            byte [] keyBytes= new byte [] {0x21,0x0a,0x03,0x23,0x45,0x29,0x78,0x12,0x35,
                                           0x45,0x67,0x78,0x21,0x13,0x34,

                                           0x56,0x67,0x45,0x12,0x9,0x38,0x0e,0x20,
                                           0x15,0x21,0x0a,0x03,0x23,0x45,0x0b,0x15,0x0c
                                          };

            byte[] encrypted= aesEncrypt(byteDataToTransmit,keyBytes);

            System.out.println("\n AES Encrypted Data is  "+new String (encrypted));

            byte [] byteDecrypt=aesDecrypt(bytestrEncrypt, keyBytes);
            System.out.println("\n AES Decrypted Data is"+byteDecrypt);
            // byte [] byteDecrypt=aesDecrypt(encrypted , keyBytes);

            //System.out.println("\n AES Decrypted Data is"+new String(byteDecrypt));
        }
        catch(Exception exp)
        {
            System.out.println(" Exception caught " + exp);
            exp.printStackTrace();
        }
    }

    public static byte[] aesEncrypt(byte[] original, byte[] key)
    {
        try
        {
            SecretKeySpec keySpec = null;
            Cipher cipher = null;
            {
                keySpec = new SecretKeySpec(key, "AES/ECB/PKCS7Padding");
                cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
                cipher.init(Cipher.ENCRYPT_MODE, keySpec); // encryption
            }
            return cipher.doFinal(original);
        }
        catch(Exception e)
        {
            //  Logger.e(e.toString());
        }
        return null;
    }

    public static byte[] aesDecrypt(byte[] encrypted, byte[] key)
    {
        try
        {
            SecretKeySpec keySpec = null;
            Cipher cipher = null;

            {
                keySpec = new SecretKeySpec(key, "AES/ECB/PKCS7Padding");

                cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
                cipher.init(Cipher.DECRYPT_MODE, keySpec);
            }

            System.out.println("In Decryprion \n"+ new String (encrypted));
            return cipher.doFinal(encrypted);

        }
        catch(Exception e)
        {
            //  Logger.e(e.toString());
        }
        return null;
    }
}

【问题讨论】:

  • 你确定输出不一样吗?在不指定文本编码的情况下使用新的 String(encrypted) 和 String.getBytes() 方法会产生不可预知的结果,因此最好在打印之前将 byte[] 转换为十六进制或 Base64。
  • 请自行格式化您的代码。我在您的代码中使用了astyle。你确定 keyspec 部分是用"AES/ECB/PKCS7Padding" 编译的吗?顺便说一句,您不应该要求 BouncyCastle 执行 ECB AES 操作。

标签: c encryption openssl aes pkcs#7


【解决方案1】:

至少您对返回的数据量的处理是关闭的。检查您的缓冲区处理!此外,在 Java 中,您使用 new String (encrypted) 而不是将字节数组转换为十六进制。

【讨论】:

    猜你喜欢
    • 2011-06-09
    • 2017-06-10
    • 1970-01-01
    • 1970-01-01
    • 2015-08-22
    • 2015-08-04
    • 1970-01-01
    • 2019-04-18
    • 1970-01-01
    相关资源
    最近更新 更多