我是密码技术的新手。我发现这段代码可以进行对称加密。
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);
它的工作。在这里,我可以使用自己的密码。那就是我需要的东西。但我不知道怎么做128或256 Symmetric Enctryption。 如何在代码中使用128和256键?
答案 0 :(得分:16)
AES是使用128位还是256位模式取决于密钥的大小,密钥长度必须为128或256位。通常,您不会将密码用作密钥,因为密码很少具有您需要的确切长度。相反,您可以使用某些密钥派生函数从密码派生加密密钥。
非常简单的示例:获取密码的MD5以获得128位密钥。如果需要256位密钥,可以使用SHA-256获取密码的256位哈希值。密钥派生函数通常运行此散列数百次并使用额外的盐。查看http://en.wikipedia.org/wiki/Key_derivation_function了解详情。
另请注意:要运行超过128位的加密,您需要从http://www.oracle.com/technetwork/java/javase/downloads/index.html下载并安装“Java Cryptography Extension(JCE)Unlimited Strength Jurisdiction Policy Files 6”。
答案 1 :(得分:6)
以下方法是使用AES加密加密字符串(valueEnc
):
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;
}
下一个方法将解密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;
}
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;
}
答案 2 :(得分:3)
您可以使用这样的简单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);
...
答案 3 :(得分:1)
来自Java's docs for Cipher.init(...)
:
public final void init(int opmode, 钥匙)
抛出: InvalidKeyException - 如果给定的键不适合初始化 这个密码,或者如果这个密码是 被初始化用于解密和 需要算法参数 不能从给定的确定 密钥,或者给定密钥是否具有密钥大小 超过允许的最大值 密钥化(由...确定) 配置的管辖区政策文件)。
对我来说,这意味着,正如Martijn Courteaux在他的评论中所说,你应该使用256位的密钥(即用一个包含32个字节的字节数组初始化SecretKeySpec),密码将接受并使用它,或拒绝它并在其大小不可接受的情况下抛出异常。
如果你遇到异常,可能是因为你没有安装无限强度加密文件,(默认的JDK安装允许128位密钥,如crypto spec document中所述)。下载无限强度加密包here。
答案 4 :(得分:0)
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;
}
}