Mac OS上的加密/解密错误

时间:2011-11-02 07:31:10

标签: java aes encryption

我对Java加密/解密知之甚少,因为我的要求很简单,将一行文本加密为十六进制字符串(所以它可以放在浏览器的URL中),我从Internet复制下面的代码,它有效,但只在Windows(XP / 7)上,在Mac上,解密后的字符串完全是一团糟,你能帮我找出哪里出错吗?

 public static String encrypt( String content, String password ) throws NoSuchAlgorithmException,
    NoSuchPaddingException, UnsupportedEncodingException, InvalidKeyException, IllegalBlockSizeException,
    BadPaddingException
{
    KeyGenerator kgen = KeyGenerator.getInstance( "AES" );
    kgen.init( 128, new SecureRandom( password.getBytes() ) );
    SecretKey secretKey = kgen.generateKey();
    byte[] enCodeFormat = secretKey.getEncoded();
    SecretKeySpec key = new SecretKeySpec( enCodeFormat, "AES" );
    Cipher cipher = Cipher.getInstance( "AES" );
    byte[] byteContent = content.getBytes( "utf-8" );
    cipher.init( Cipher.ENCRYPT_MODE, key );
    byte[] result = cipher.doFinal( byteContent );
    return parseByte2HexStr( result );
}


public static String decrypt( String contents, String password ) throws NoSuchAlgorithmException,
    NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException
{
    byte[] content = parseHexStr2Byte( contents );
    KeyGenerator kgen = KeyGenerator.getInstance( "AES" );
    kgen.init( 128, new SecureRandom( password.getBytes() ) );
    SecretKey secretKey = kgen.generateKey();
    byte[] enCodeFormat = secretKey.getEncoded();
    SecretKeySpec key = new SecretKeySpec( enCodeFormat, "AES" );
    Cipher cipher = Cipher.getInstance( "AES" );  
    cipher.init( Cipher.DECRYPT_MODE, key );
    byte[] result = cipher.doFinal( content );
    return new String( result ); 
}


public static String parseByte2HexStr( byte buf[] )
{
    StringBuffer sb = new StringBuffer();
    for( int i = 0; i < buf.length; i++ )
    {
        String hex = Integer.toHexString( buf[i] & 0xFF );
        if( hex.length() == 1 )
        {
            hex = '0' + hex;
        }
        sb.append( hex.toUpperCase() );
    }
    return sb.toString();
}


public static byte[] parseHexStr2Byte( String hexStr )
{
    if( hexStr.length() < 1 )
        return null;
    byte[] result = new byte[ hexStr.length() / 2 ];
    for( int i = 0; i < hexStr.length() / 2; i++ )
    {
        int high = Integer.parseInt( hexStr.substring( i * 2, i * 2 + 1 ), 16 );
        int low = Integer.parseInt( hexStr.substring( i * 2 + 1, i * 2 + 2 ), 16 );
        result[i] = ( byte ) ( high * 16 + low );
    }
    return result;
}

1 个答案:

答案 0 :(得分:1)

不要从“互联网”中复制代码,因为那里有很多废话,因为你正在找到困难的方法。此代码至少有2个重要错误。

  1. 错误地假设如果您向SecureRandom提供种子,则该种子是用于为SecureRandom实例设定种子的唯一数据。
  2. 使用String.getBytes()方法中的默认字符集。几乎总是你应该明确指定用于加密的UTF-8字符集。
  3. 在你的情况下,#1可能是问题,#2可能不会伤害你。

    正确的解决方案是使用正确的基于密码的加密(PBE)算法。不幸的是,Sun提供商不支持任何基于AES的PBE算法。如果将bouncycastle提供程序添加到项目中,则可以获得基于AES的PBE算法。