Java 使用 AES 256 和 128 对称密钥加密
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6538485/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java using AES 256 and 128 Symmetric-key encryption
提问by Bhuban
I am new in cipher technology. I found this code to do Symmetric Encryption.
我是密码技术的新手。我发现此代码可以进行对称加密。
byte[] key = //... secret sequence of bytes
byte[] dataToSend = ...
Cipher c = Cipher.getInstance("AES");
SecretKeySpec k = new SecretKeySpec(key, "AES");
c.init(Cipher.ENCRYPT_MODE, k);
byte[] encryptedData = c.doFinal(dataToSend);
Its working. Here I can use my own password. And thats what exactly I needed. But I dont know how to do 128 or 256 Symmetric Enctryption. How can I use 128 and 256 key into my code ?
它的工作。在这里我可以使用我自己的密码。而这正是我所需要的。但我不知道如何进行 128 或 256 对称加密。如何在我的代码中使用 128 和 256 键?
采纳答案by Peter ?tibrany
Whether AES uses 128 or 256 bit mode depends on size of your key, which must be 128 or 256 bits long. Typically you don't use your password as a key, because passwords rarely have exact length as you need. Instead, you derive encryption key from your password by using some key derivation function.
AES 使用 128 位模式还是 256 位模式取决于您的密钥的大小,其长度必须为 128 位或 256 位。通常,您不使用密码作为密钥,因为密码很少有您需要的确切长度。相反,您可以使用某些密钥派生函数从密码中派生出加密密钥。
Very simple example: take MD5 of your password to get 128-bit key.If you want 256-bit key, you can use SHA-256 to get 256-bit hash of your password. Key-derivation functions usually run this hashing several hundreds time and use extra salt as well. Check out http://en.wikipedia.org/wiki/Key_derivation_functionfor details.
非常简单的例子:用你的密码的 MD5 来获得 128 位的密钥。如果您需要 256 位密钥,可以使用 SHA-256 来获取密码的 256 位哈希值。密钥派生函数通常会运行数百次这种哈希并使用额外的盐。查看http://en.wikipedia.org/wiki/Key_derivation_function了解详细信息。
Also note: to run encryption stronger than 128-bit you will need to download and install 'Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6' from http://www.oracle.com/technetwork/java/javase/downloads/index.html.
另请注意:要运行比 128 位更强的加密,您需要从http://www.oracle.com/technetwork/java/javase/downloads下载并安装“Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6” /index.html。
回答by Gergely Bacso
You can use a simple KeyGenerator object like this:
您可以像这样使用一个简单的 KeyGenerator 对象:
KeyGenerator generator = KeyGenerator.getInstance("AES/CTR/PKCS5PADDING");
generator.init(128);
SecretKey key = generator.generateKey();
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key);
...
回答by JB Nizet
From Java's docs for Cipher.init(...)
:
public final void init(int opmode, Key key)
Throws: InvalidKeyException - if the given key is inappropriate for initializing this cipher, or if this cipher is being initialized for decryption and requires algorithm parameters that cannot be determined from the given key, or if the given key has a keysize that exceeds the maximum allowable keysize (as determined from the configured jurisdiction policy files).
public final void init(int opmode, Key key)
抛出: InvalidKeyException - 如果给定的密钥不适合初始化此密码,或者如果此密码正在初始化以进行解密并且需要无法从给定密钥确定的算法参数,或者给定密钥的密钥大小超过允许的最大值密钥大小(根据配置的权限策略文件确定)。
To me, this means that, as Martijn Courteaux said in his comment, you should use a key of 256 bits (i.e. initialize the SecretKeySpec with a byte array containing 32 bytes), and the cipher will accept it and use it, or reject it and throw an exception if its size is not acceptable.
对我来说,这意味着,正如 Martijn Courteaux 在他的评论中所说,你应该使用 256 位的密钥(即用包含 32 个字节的字节数组初始化 SecretKeySpec),密码将接受它并使用它,或者拒绝它并在其大小不可接受时抛出异常。
If you get an exception, it's probably because you have not installed the unlimited strength crypto files, (the default JDK install allows 128 bit keys as documented in this crypto spec document). Download unlimited strength crypto package here.
如果出现异常,可能是因为您没有安装无限强度的加密文件(默认 JDK 安装允许 128 位密钥,如本加密规范文档中所述)。在这里下载无限强度的加密包。
回答by Technical
public class CipherUtils
{
private static byte[] key = {
0x74, 0x68, 0x69, 0x73, 0x49, 0x73, 0x41, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79
};//"thisIsASecretKey";
public static String encrypt(String strToEncrypt)
{
try
{
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
final SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
final String encryptedString = Base64.encodeBase64String(cipher.doFinal(strToEncrypt.getBytes()));
return encryptedString;
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
}
回答by Technical
The Answer for 128 bit
128 位的答案
The following method is to encrypt a string (valueEnc
) with AES encryption:
以下方法是valueEnc
使用 AES 加密对字符串 ( ) 进行加密:
private static final String ALGORITHM = "AES";
public String encrypt(final String valueEnc, final String secKey) {
String encryptedVal = null;
try {
final Key key = generateKeyFromString(secKey);
final Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.ENCRYPT_MODE, key);
final byte[] encValue = c.doFinal(valueEnc.getBytes());
encryptedVal = new BASE64Encoder().encode(encValue);
} catch(Exception ex) {
System.out.println("The Exception is=" + ex);
}
return encryptedVal;
}
The next method will decrypt the AES encrypted string (encryptedVal
):
下一个方法将解密 AES 加密字符串 ( encryptedVal
):
public String decrypt(final String encryptedValue, final String secretKey) {
String decryptedValue = null;
try {
final Key key = generateKeyFromString(secretKey);
final Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.DECRYPT_MODE, key);
final byte[] decorVal = new BASE64Decoder().decodeBuffer(encryptedValue);
final byte[] decValue = c.doFinal(decorVal);
decryptedValue = new String(decValue);
} catch(Exception ex) {
System.out.println("The Exception is=" + ex);
}
return decryptedValue;
}
The secKey
is a 128-bit key, which is encoded in the BASE64Encoder
. The BASE64Decoder
in the following method generates an appropriate 128-bit key
的secKey
是一个128位的密钥,这是在编码BASE64Encoder
。将BASE64Decoder
在下面的方法产生一个适当的128位密钥
private Key generateKeyFromString(final String secKey) throws Exception {
final byte[] keyVal = new BASE64Decoder().decodeBuffer(secKey);
final Key key = new SecretKeySpec(keyVal, ALGORITHM);
return key;
}