Ошибка шифрования / дешифрования в Mac OS - PullRequest
0 голосов
/ 02 ноября 2011

Я мало что знал о шифровании / дешифровании Java, так как мое требование простое: зашифровать одну строку текста в шестнадцатеричную строку (чтобы ее можно было вставить в URL браузера), я скопировал приведенный ниже код из Интернета: работает, но только в 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 Ответ

1 голос
/ 02 ноября 2011

Не копируйте код из "интернета", потому что там много дерьма, потому что вы находите трудный путь.В этом коде есть как минимум 2 значительных ошибки.

  1. Неправильно предполагается, что если вы передаете SecureRandom начальное значение, то это начальное значение - единственные данные, используемые для заполнения экземпляра SecureRandom.
  2. Используеткодировка по умолчанию в методе String.getBytes ().Почти всегда вы должны явно указывать кодировку UTF-8 для криптографического использования.

В вашем случае, вероятно, проблема # 1, вероятно, # 2 вас не ранит.

ПравильноРешение заключается в использовании правильного алгоритма шифрования на основе пароля (PBE).К сожалению, поставщики Sun не поддерживают алгоритмы PBE на основе AES.Если вы добавите провайдера bouncycastle в свой проект, то сможете получить алгоритмы PBE на основе AES.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...