简体   繁体   English

AES加密我正在尝试使用AES加密进行加密

[英]AES Encryption I am trying to encrypt using AES encryption

I just want to migrate the ruby code to Java 我只想将ruby代码迁移到Java

here is my ruby code 这是我的红宝石代码

require 'openssl'
require 'base64'

key = '7c54367a45b37a192abc2cd7f45203042350406f8'
cipher = OpenSSL::Cipher::Cipher.new('aes-128-ecb')
cipher.encrypt()


cipher = OpenSSL::Cipher::Cipher.new('aes-256-ecb')
cipher.encrypt()
cipher.key = key

crypt = cipher.update('Rahul')
crypt << cipher.final()

puts (Base64.encode64(crypt))

Here is what i am trying in Java 这是我在Java中尝试的内容

String getDecodedString(String key,String encodedValue,SupportedEncryptionAlgorithm algoInfo) 
{
    Cipher cipher = getCipherInstancenew(algoInfo, key,Cipher.DECRYPT_MODE);
    try
    {
        byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(encodedValue);

        int ctLength = cipher.getOutputSize(dec.length);
        byte[] plainText = new byte[cipher.getOutputSize(ctLength)];

        int ptLength = cipher.update(dec, 0, ctLength, plainText, 0);
        ptLength += cipher.doFinal(plainText, ptLength);

        return null; 
    }
    catch (IllegalBlockSizeException e)
    {
        LoggerFactory.getLogger(EncryptionHelper.class).error("Security Alert",e);
    }
    catch (BadPaddingException e)
    {
        LoggerFactory.getLogger(EncryptionHelper.class).error("Security Alert",e);
    }
    return null;
}

public static byte[] stringToBytes(String s) {
    byte[] b2 = new BigInteger(s, 36).toByteArray();
    return Arrays.copyOfRange(b2, 1, b2.length);
}

public static Cipher getCipherInstancenew(SupportedEncryptionAlgorithm algoInfo,String keyString,int mode) throws IOException
{
    byte[] decodedBytes;
    Cipher cipher=null;      
    try
    {
        decodedBytes = getBase64FromHEX(keyString).getBytes();
        SecretKeySpec skeySpec = new SecretKeySpec(decodedBytes, "AES");
        Security.addProvider(new BouncyCastleProvider());   
        cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "BC");
        cipher.init(mode, skeySpec );
    }
    catch (java.security.GeneralSecurityException e)
    {
        /*Strictly no logging as it is security class 
         *  There seems to be some issue with the Keys so alert it */
         //LoggerFactory.getLogger(EncryptionHelper.class).error("Security Alert",e);
         throw new IOException("GetCipherInstance does not exsists");
    }

    return cipher;

}

public static String getBase64FromHEX(String input) {

    byte barr[] = new byte[16];
    int bcnt = 0;
    for (int i = 0; i < 32; i += 2) {
        char c1 = input.charAt(i);
        char c2 = input.charAt(i + 1);
        int i1 = intFromChar(c1);
        int i2 = intFromChar(c2);

        barr[bcnt] = 0;
        barr[bcnt] |= (byte) ((i1 & 0x0F) << 4);
        barr[bcnt] |= (byte) (i2 & 0x0F);
        bcnt++;
    }

    BASE64Encoder encoder = new BASE64Encoder();
    return encoder.encode(barr);
}

private static int intFromChar(char c) {
    char[] carr = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

    char clower = Character.toLowerCase(c);
    for (int i = 0; i < carr.length; i++) {
        if (clower == carr[i]) {
            return i;
        }
    }

    return 0;
}

It works with 32 byte String but not with the 41 bytes in Java but in Ruby it works for any length greater than 32 byte Strange Please help 它适用于32字节字符串,但不适用于Java中的41字节,但在Ruby中,它适用于大于32字节的任何长度Strange请帮助

I doubt that your calls to String.getBytes() are doing what you need them to do. 我怀疑你对String.getBytes()调用正在做你需要他们做的事情。

The getBytes() method uses the platform's default character encoding to convert the characters of a String to a sequence of bytes. getBytes()方法使用平台的默认字符编码将String的字符转换为字节序列。 The default platform character encoding is something like UTF-8, US-ASCII, or ISO-8859-1. 默认平台字符编码类似于UTF-8,US-ASCII或ISO-8859-1。 It's not base-64 or hexadecimal. 它不是base-64或十六进制。

Most character encodings can't handle the random 8-bit values that are used in cryptographic operations. 大多数字符编码无法处理加密操作中使用的随机8位值。 So, for example, you generally can't create a new String from the bytes that result from encryption. 因此,例如,您通常无法根据加密产生的字节创建新的String Many of the values will be replaced with or ?, depending on your encoding. 许多值将替换为 或?,具体取决于您的编码。 And, even if it happens to work on your machine, the machine on the next desk could be configured differently, and will fail when trying to decode that character string. 而且,即使它恰好在您的计算机上运行,​​下一个桌面上的计算机也可能配置不同,并且在尝试解码该字符串时将失败。

If you need to convert between binary data and text, use an encoding like Base-64. 如果需要在二进制数据和文本之间进行转换,请使用Base-64之类的编码。

The below Java code outputs the exact same base 64 encoded result from encrypting as the Ruby code and successfully decrypts it: 下面的Java代码输出完全相同的base 64编码结果,加密为Ruby代码并成功解密它:

final Cipher encryptCipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "BC");
encryptCipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec("7c54367a45b37a192abc2cd7f4520304".getBytes(), "AES"));
final byte[] encrypt = encryptCipher.doFinal("This is my text".getBytes());
System.out.println(new String(Base64.encode(encrypt)));

final Cipher decryptCipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "BC");
decryptCipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec("7c54367a45b37a192abc2cd7f4520304".getBytes(), "AES"));
final byte[] decrypt = decryptCipher.doFinal(encrypt);
System.out.println(new String(decrypt));

The Ruby OpenSSL API is apparently only using the first 32 bytes of the key, since the following value for key returns the same value as the 41 byte version: 红宝石OpenSSL的API显然仅使用前32个字节的关键的,因为用于将下面的值key返回相同的值作为41字节版本:

key = '7c54367a45b37a192abc2cd7f4520304'

Also, I'm not sure why cipher is initialized twice in the Ruby code as it isn't necessary as far as I can tell. 另外,我不确定为什么cipher在Ruby代码中被初始化两次,因为就我所知,这是不必要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM