我想将String转换为secretKey
public void generateCode(String keyStr){
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128); // 192 and 256 bits may not be available
// Generate the secret key specs.
secretKey skey=keyStr; //How can I make the casting here
//SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
}
我尝试使用BASE64Decoder而不是secretKey,但我遇到的问题是我无法指定密钥长度。
修改 我想从其他地方调用此函数
static public String encrypt(String message , String key , int keyLength) throws Exception {
// Get the KeyGenerator
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(keyLength); // 192 and 256 bits may not be available
// Generate the secret key specs.
SecretKey skey = key; //here is the error
byte[] raw = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
// Instantiate the cipher
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
System.out.println("msg is" + message + "\n raw is" + raw);
byte[] encrypted = cipher.doFinal(message.getBytes());
String cryptedValue = new String(encrypted);
System.out.println("encrypted string: " + cryptedValue);
return cryptedValue;
}
如果有人可以提供帮助,我会非常感激。
答案 0 :(得分:37)
由于这些特殊原因,没有完整性检查
"AES/GCM/NoPadding"
模式仅适用于Java 7以后的如果您在双方都实施了GCM模式 - 例如在Java 6上使用Bouncy Castle - 请继续使用它,因为它更加安全(只要“IV”非常独特)。改变实施应该很容易。
有关加密的实施说明
InvalidArgumentException
返回。"UTF-8"
和"AES/CBC/PKCS5Padding"
必需。其他一些注释
new String(byte[])
)。该方法可能会无声地失败!CipherStream
实现。好的,这里有一些代码......
public static String encrypt(final String plainMessage,
final String symKeyHex) {
final byte[] symKeyData = DatatypeConverter.parseHexBinary(symKeyHex);
final byte[] encodedMessage = plainMessage.getBytes(Charset
.forName("UTF-8"));
try {
final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
final int blockSize = cipher.getBlockSize();
// create the key
final SecretKeySpec symKey = new SecretKeySpec(symKeyData, "AES");
// generate random IV using block size (possibly create a method for
// this)
final byte[] ivData = new byte[blockSize];
final SecureRandom rnd = SecureRandom.getInstance("SHA1PRNG");
rnd.nextBytes(ivData);
final IvParameterSpec iv = new IvParameterSpec(ivData);
cipher.init(Cipher.ENCRYPT_MODE, symKey, iv);
final byte[] encryptedMessage = cipher.doFinal(encodedMessage);
// concatenate IV and encrypted message
final byte[] ivAndEncryptedMessage = new byte[ivData.length
+ encryptedMessage.length];
System.arraycopy(ivData, 0, ivAndEncryptedMessage, 0, blockSize);
System.arraycopy(encryptedMessage, 0, ivAndEncryptedMessage,
blockSize, encryptedMessage.length);
final String ivAndEncryptedMessageBase64 = DatatypeConverter
.printBase64Binary(ivAndEncryptedMessage);
return ivAndEncryptedMessageBase64;
} catch (InvalidKeyException e) {
throw new IllegalArgumentException(
"key argument does not contain a valid AES key");
} catch (GeneralSecurityException e) {
throw new IllegalStateException(
"Unexpected exception during encryption", e);
}
}
public static String decrypt(final String ivAndEncryptedMessageBase64,
final String symKeyHex) {
final byte[] symKeyData = DatatypeConverter.parseHexBinary(symKeyHex);
final byte[] ivAndEncryptedMessage = DatatypeConverter
.parseBase64Binary(ivAndEncryptedMessageBase64);
try {
final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
final int blockSize = cipher.getBlockSize();
// create the key
final SecretKeySpec symKey = new SecretKeySpec(symKeyData, "AES");
// retrieve random IV from start of the received message
final byte[] ivData = new byte[blockSize];
System.arraycopy(ivAndEncryptedMessage, 0, ivData, 0, blockSize);
final IvParameterSpec iv = new IvParameterSpec(ivData);
// retrieve the encrypted message itself
final byte[] encryptedMessage = new byte[ivAndEncryptedMessage.length
- blockSize];
System.arraycopy(ivAndEncryptedMessage, blockSize,
encryptedMessage, 0, encryptedMessage.length);
cipher.init(Cipher.DECRYPT_MODE, symKey, iv);
final byte[] encodedMessage = cipher.doFinal(encryptedMessage);
// concatenate IV and encrypted message
final String message = new String(encodedMessage,
Charset.forName("UTF-8"));
return message;
} catch (InvalidKeyException e) {
throw new IllegalArgumentException(
"key argument does not contain a valid AES key");
} catch (BadPaddingException e) {
// you'd better know about padding oracle attacks
return null;
} catch (GeneralSecurityException e) {
throw new IllegalStateException(
"Unexpected exception during decryption", e);
}
}
用法:
String plain = "Zaphod's just zis guy, ya knöw?";
String encrypted = encrypt(plain, "000102030405060708090A0B0C0D0E0F");
System.out.println(encrypted);
String decrypted = decrypt(encrypted, "000102030405060708090A0B0C0D0E0F");
if (decrypted != null && decrypted.equals(plain)) {
System.out.println("Hey! " + decrypted);
} else {
System.out.println("Bummer!");
}
答案 1 :(得分:3)
这里是使用Base64 Util类而不是DatatypeConverter
的版本public static String encrypt(final String plainMessage,
final String symKeyHex) {
final byte[] symKeyData = Base64.decode(symKeyHex,Base64.DEFAULT);
final byte[] encodedMessage = plainMessage.getBytes(Charset
.forName("UTF-8"));
try {
final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
final int blockSize = cipher.getBlockSize();
// create the key
final SecretKeySpec symKey = new SecretKeySpec(symKeyData, "AES");
// generate random IV using block size (possibly create a method for
// this)
final byte[] ivData = new byte[blockSize];
final SecureRandom rnd = SecureRandom.getInstance("SHA1PRNG");
rnd.nextBytes(ivData);
final IvParameterSpec iv = new IvParameterSpec(ivData);
cipher.init(Cipher.ENCRYPT_MODE, symKey, iv);
final byte[] encryptedMessage = cipher.doFinal(encodedMessage);
// concatenate IV and encrypted message
final byte[] ivAndEncryptedMessage = new byte[ivData.length
+ encryptedMessage.length];
System.arraycopy(ivData, 0, ivAndEncryptedMessage, 0, blockSize);
System.arraycopy(encryptedMessage, 0, ivAndEncryptedMessage,
blockSize, encryptedMessage.length);
final String ivAndEncryptedMessageBase64 = Base64.encodeToString(ivAndEncryptedMessage,Base64.DEFAULT);
return ivAndEncryptedMessageBase64;
} catch (InvalidKeyException e) {
throw new IllegalArgumentException(
"key argument does not contain a valid AES key");
} catch (GeneralSecurityException e) {
throw new IllegalStateException(
"Unexpected exception during encryption", e);
}
}
public static String decrypt(final String ivAndEncryptedMessageBase64,
final String symKeyHex) {
final byte[] symKeyData = Base64.decode((symKeyHex),Base64.DEFAULT);
final byte[] ivAndEncryptedMessage = Base64.decode(ivAndEncryptedMessageBase64,Base64.DEFAULT);
try {
final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
final int blockSize = cipher.getBlockSize();
// create the key
final SecretKeySpec symKey = new SecretKeySpec(symKeyData, "AES");
// retrieve random IV from start of the received message
final byte[] ivData = new byte[blockSize];
System.arraycopy(ivAndEncryptedMessage, 0, ivData, 0, blockSize);
final IvParameterSpec iv = new IvParameterSpec(ivData);
// retrieve the encrypted message itself
final byte[] encryptedMessage = new byte[ivAndEncryptedMessage.length
- blockSize];
System.arraycopy(ivAndEncryptedMessage, blockSize,
encryptedMessage, 0, encryptedMessage.length);
cipher.init(Cipher.DECRYPT_MODE, symKey, iv);
final byte[] encodedMessage = cipher.doFinal(encryptedMessage);
// concatenate IV and encrypted message
final String message = new String(encodedMessage,
Charset.forName("UTF-8"));
return message;
} catch (InvalidKeyException e) {
throw new IllegalArgumentException(
"key argument does not contain a valid AES key");
} catch (BadPaddingException e) {
// you'd better know about padding oracle attacks
return null;
} catch (GeneralSecurityException e) {
throw new IllegalStateException(
"Unexpected exception during decryption", e);
}
}
提醒那些获得Padding异常的人。确保使用正确的密钥长度。提示:看看Maarten的帖子:他的十六进制正好是32;)这并非巧合:)