0
SecureRandom random = new SecureRandom(); // quite heavy, look into a lighter method.

String stringToEncrypt = "mypassword";
byte[] realiv = new byte[16];
random.nextBytes(realiv);
Cipher ecipher = Cipher.getInstance("AES");

SecureRandom random = new SecureRandom(); // quite heavy, look into a lighter method.

byte[] realiv = new byte[16];
random.nextBytes(realiv);       

byte[] secret = "somelongsecretkey".getBytes();
SecretKeySpec secretKey = new SecretKeySpec(secret, "AES");
ecipher.init(Cipher.ENCRYPT_MODE, secretKey, random);
byte[] encryptedData = ecipher.doFinal();

ただし、init()3つのパラメーターのみを受け取ります。次のような方法が必要です。

ecipher.init(Cipher.ENCRYPT_MODE, stringToEncrypt, secretKey, random);
4

2 に答える 2

5

一般に、決定論的な動作を持つアルゴリズムの乱数を生成するものは必要ありません。さらに、Java のデフォルトである ECB ブロック モードを使用している場合、IV は必要ありません。正確には、Java のデフォルトは"AES/ECB/PKCS5Padding"for inCipher.getInstance("AES")です。

したがって、次のようなコードで問題ないはずです。

// lets use the actual key value instead of the platform specific character decoding
byte[] secret = Hex.decodeHex("25d6c7fe35b9979a161f2136cd13b0ff".toCharArray());

// that's fine
SecretKeySpec secretKey = new SecretKeySpec(secret, "AES");

// SecureRandom should either be slow or be implemented in hardware
SecureRandom random = new SecureRandom();

// first create the cipher
Cipher eCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

// filled with 00h characters first, use Cipher instance so you can switch algorithms
byte[] realIV = new byte[eCipher.getBlockSize()];

// actually fill with random
random.nextBytes(realIV);

// MISSING: create IvParameterSpec
IvParameterSpec ivSpec = new IvParameterSpec(realIV);

// create the cipher using the IV
eCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);

// NOTE: you should really not encrypt passwords for verification
String stringToEncrypt = "mypassword";

// convert to bytes first, but don't use the platform encoding
byte[] dataToEncrypt = stringToEncrypt.getBytes(Charset.forName("UTF-8"));

// actually do the encryption using the data
byte[] encryptedData = eCipher.doFinal(dataToEncrypt);

これで、見た目がずっと良くなりました。16 進文字列のデコードには Apache commons コーデックを使用しました。

realIVを で保存する必要があり、MAC などの完全性保護を含めていないことに注意してくださいencryptedData(ただし、パスワードの場合は必要ないかもしれません)。

于 2012-11-03T12:26:17.343 に答える
1

あなたがやりたいことはecipher.doFinal(stringToEncrypt)、おそらく一連のdoUpdate(...)文字列が長い場合の後に、 call であると強く思います。

.init()暗号オブジェクトを作成し、暗号化された出力update()doFinal()入力して、平文を入力として受け取ります。

もちろん、と byte arrayの間で変換するString必要があります。

于 2012-11-03T01:19:00.427 に答える