我想输入我自己的String变量,然后将其转换为AES算法的加密/解密密钥。我尝试了许多已知的方法,如UTF-8,base64,一些方法做转换字节串,反之亦然等等。虽然所有这些都能正常工作,但是其中一些不能正常工作,但它们都以字节为单位转换字符串,但我想要的是输入类似" helloWorld"并获取AES的128位密钥。我使用它的任何东西都用于"密钥长度无效"因为字节不准确。 我需要做什么才能获得正确的字节?另外我想澄清一下,我想要String而不是char数组,因为我想在以后的程序中将它作为一个函数,以便用户可以随意更改密钥。
更新:我编辑了这个例子,这个我到目前为止,仍然抛出了关于参数和密钥长度的异常
public class SHAHashingExample
{
private static byte[] keyValue;
public static void main(String[] args)throws Exception
{
String password = "123456";
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(password.getBytes());
byte byteData[] = md.digest();
keyValue = md.digest();
//convert the byte to hex format method 1
StringBuffer sb = new StringBuffer();
for (int i = 0; i < byteData.length/2; i++) {
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
}
System.out.println("Hex format : " + sb.toString());
//convert the byte to hex format method 2
StringBuffer hexString = new StringBuffer();
for (int i=0;i<byteData.length/2;i++) {
String hex=Integer.toHexString(0xff & byteData[i]);
if(hex.length()==1) hexString.append('0');
hexString.append(hex);
}
System.out.println("Hex format : " + hexString.toString());
String k = "hello world";
String f = encrypt(k);
System.out.println(f);
String j = decrypt(f);
System.out.println(j);
}
public static String encrypt(String Data) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = c.doFinal(Data.getBytes());
String encryptedValue = new BASE64Encoder().encode(encVal);
return encryptedValue;
}
public static String decrypt(String encryptedData) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.DECRYPT_MODE, key);
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
byte[] decValue = c.doFinal(decordedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
}
private static Key generateKey() throws Exception {
Key key = new SecretKeySpec(keyValue, "AES");
return key;
}
}
答案 0 :(得分:2)
更新2: 原来你对Java Cipher功能的许多组件的使用都没有发现。看看这个其他的答案。
更新1: 要使用下面的示例将256位值降低到128位,您可以尝试以下操作:
// After you already have generated the digest
byte[] mdbytes = md.digest();
byte[] key = new byte[mdbytes.length / 2];
for(int I = 0; I < key.length; I++){
// Choice 1 for using only 128 bits of the 256 generated
key[I] = mdbytes[I];
// Choice 2 for using ALL of the 256 bits generated
key[I] = mdbytes[I] ^ mdbytes[I + key.length];
}
// Now use key as the input key for AES
<强> ORIGINAL:强> 这是使用内置java API在某些数据字节上执行SHA哈希的一个很好的例子。
http://www.mkyong.com/java/java-sha-hashing-example/
Java具有执行多种不同哈希类型的内置功能,您应该尝试利用其中一种,而不是尝试自己编写一种。也许最广泛使用的哈希函数是SHA版本。有些版本可以输出128,256和512位散列输出。
您要求的是,在所有技术方面确切地说,使用您的密码登录系统通常是如何工作的。系统永远不会真正存储您的实际文本密码,而是存储HASH。当您(用户)输入密码时,系统会对您输入的内容执行实时哈希,并将实时生成的哈希值与存储的哈希值进行比较。这不会增加一步,假设使用该哈希作为对称加密的实际关键组件。通常,GOOD哈希确实可以生成DECENT密钥材料以用于实际的对称加密/解密。
答案 1 :(得分:0)
您要找的是hash function。您将能够输入任意长度的输入,并且散列函数将始终输出固定位大小的值 - 在您的情况下为128位。
哈希函数有很多种方法。最简单的一个是在输入数字(例如字符串的整数表示)和 n 位中可以表示的最大数字之间进行modulo operation(在您的情况下) ,128);输出结果将是 n 位数,您可以将其转换为您想要的任何形式(可能是十六进制)并将其用作AES密钥。
这并不一定有效(也就是说,输出128位密钥可能不会在0和2 ^ 128 - 1之间非常均匀地分布),但更重要的是,它会非常慢没有充分的理由。一些有效的128位散列函数是CityHash和MurmurHash - 您可以在Google上查看更多(以及几个Java实现)。