AES 加密问题
我正在开发一个项目,需要使用 AES 加密字符串。该程序需要能够接收字符串并输出十六进制加密字符串以及密钥,或者使用用户指定的密钥和字符串输出未加密的文本(也就是说,程序需要能够要在不同的情况下执行这两件事,即我应该能够在我的计算机上输入“1234”并输出“加密文本:asdf密钥:ghjk”;我的朋友应该能够输入“加密文本: asdf KEY: ghjk" 并退出 "1234" )
到目前为止,这是我所拥有的:
package betterencryption;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.util.Scanner;
public class BetterEncryption {
public static String asHex (byte buf[]) { //asHex works just fine, it's the main that's
//giving me trouble
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10)
strbuf.append("0");
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
return strbuf.toString();
}
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
KeyGenerator kgen = KeyGenerator.getInstance("AES");kgen.init(128);
SecretKey skey = kgen.generateKey();
byte[] bytes = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(bytes, "AES");
Cipher cipher = Cipher.getInstance("AES");
System.out.print("Do you want to encrypt or unencrypt?\n");/*This is a weird way of doing it,*/
String choice = sc.next(); char cc = choice.charAt(2); /*I know, but this part checks to see if*/
if(cc=='c'){ /*the program is to encrypt or unencrypt*/
System.out.print("Enter a string to encrypt: "); /* a string. The 'encrypt' function works.*/
String message = sc.next();
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal((args.length == 0 ? message : args[0]).getBytes());
System.out.println("Encrypted string: " + asHex(encrypted)+"\nKey: "+asHex(bytes));
//^This^ section actually works! The code outputs an encrypted string and everything.
//It's beautiful
//Unfortunately getting that string back into readable text has been problematic
//Which is where you guys come in!
//Hopefully
}
if(true){
System.out.print("\nEnter the encrypted string: "); String encryptedString = sc.next();
System.out.print("\nEnter the key: "); String keyString = sc.next();
int len = encryptedString.length(); /*this section converts the user-input string*/
byte[] encrypted = new byte[len / 2]; /*into an array of bytes*/
for (int i = 0; i < len; i += 2) { /*I'm not sure if it works, though*/
encrypted[i / 2] = (byte) ((Character.digit(encryptedString.charAt(i), 16) << 4)+
Character.digit(encryptedString.charAt(i+1), 16));
cipher.init(Cipher.DECRYPT_MODE, skeySpec); /*as you can see, I haven't even begun to implement*/
byte[] original = cipher.doFinal(encrypted);/*a way to allow the user-input key to be used.*/
String originalString = new String(original);
System.out.println("\nOriginal string: "+originalString); //I'm really quite stuck.
//can you guys help?
}
}
}
}
好吧,希望有人可以帮助我。
编辑:
我最大的问题是将字符串加密字符串转换为 sKeySpec 并弄清楚如何防止“解密”函数给用户一个错误,指出他们输入的字符串没有正确填充。我知道这不是真的,因为我尝试加密一个字符串,然后将其加密形式粘贴到解密器中,结果却出现错误。如果我消除所有“if”条件并让它加密一个字符串,然后在同一实例中解密它,则该程序可以正常工作;我认为这是由于 keyGen 的随机密钥的保存
I'm working on a project and I need to encrypt a String with AES. The program needs to take be able to either take in a String and output an encrypted string in hex, along with a key, or, using a user-specified key and string, output unencrypted text (that is, the program needs to be able to do both of these things in different instances i.e. I should be able to put in "1234" on my machine and get out "Encrypted text: asdf Key: ghjk"; my friend should be able to put in "Encrypted text: asdf KEy: ghjk" on his and get out "1234" )
Here's what I have so far:
package betterencryption;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.util.Scanner;
public class BetterEncryption {
public static String asHex (byte buf[]) { //asHex works just fine, it's the main that's
//giving me trouble
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10)
strbuf.append("0");
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
return strbuf.toString();
}
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
KeyGenerator kgen = KeyGenerator.getInstance("AES");kgen.init(128);
SecretKey skey = kgen.generateKey();
byte[] bytes = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(bytes, "AES");
Cipher cipher = Cipher.getInstance("AES");
System.out.print("Do you want to encrypt or unencrypt?\n");/*This is a weird way of doing it,*/
String choice = sc.next(); char cc = choice.charAt(2); /*I know, but this part checks to see if*/
if(cc=='c'){ /*the program is to encrypt or unencrypt*/
System.out.print("Enter a string to encrypt: "); /* a string. The 'encrypt' function works.*/
String message = sc.next();
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal((args.length == 0 ? message : args[0]).getBytes());
System.out.println("Encrypted string: " + asHex(encrypted)+"\nKey: "+asHex(bytes));
//^This^ section actually works! The code outputs an encrypted string and everything.
//It's beautiful
//Unfortunately getting that string back into readable text has been problematic
//Which is where you guys come in!
//Hopefully
}
if(true){
System.out.print("\nEnter the encrypted string: "); String encryptedString = sc.next();
System.out.print("\nEnter the key: "); String keyString = sc.next();
int len = encryptedString.length(); /*this section converts the user-input string*/
byte[] encrypted = new byte[len / 2]; /*into an array of bytes*/
for (int i = 0; i < len; i += 2) { /*I'm not sure if it works, though*/
encrypted[i / 2] = (byte) ((Character.digit(encryptedString.charAt(i), 16) << 4)+
Character.digit(encryptedString.charAt(i+1), 16));
cipher.init(Cipher.DECRYPT_MODE, skeySpec); /*as you can see, I haven't even begun to implement*/
byte[] original = cipher.doFinal(encrypted);/*a way to allow the user-input key to be used.*/
String originalString = new String(original);
System.out.println("\nOriginal string: "+originalString); //I'm really quite stuck.
//can you guys help?
}
}
}
}
Well, hopefully someone can help me.
EDIT:
My biggest problems are converting String encryptedString into an sKeySpec and figuring out how to prevent the 'unencrypt' function from giving the user an error saying that the String they input was not properly padded. I know this isn't true because I've tried encrypting a String and then pasting what the encrypted form of it is into the unencryptor only to get an error. The program works fine if I eliminate all the "if" conditions and just have it encrypt a String and then unencrypt it in the same instance; I think this is due to the preservation of keyGen's Random Key
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的问题是这样的:
正如您编写的那样,您的程序每次运行时都会生成一个新的随机密钥,该密钥永远不会在任何地方保存或显示。使用此密钥加密的任何内容实际上都无法解密。
您需要做的是想出一些方案来根据用户输入生成密钥,而不是使用
KeyGenerator
随机生成它。该计划如何运作取决于您。Your problem is this:
As you've written it, your program is generating a new, random key every time it's run, which is never saved or displayed anywhere. Anything that you're encrypting with this key is effectively impossible to decrypt.
What you'll need to do is come up with some scheme for generating a secret key from the user input, rather than randomly generating it using
KeyGenerator
. How that scheme will work is up to you.根据您使用的 AES 变体,您的密钥长度需要为 128、192 或 256 位。
您可以使用哈希算法根据用户输入生成具有特定长度的密钥。
另请参阅:java-aes-and-using-my-own-key
Depending on which AES Variant you use, your key needs to be 128, 192 or 256Bit long.
You can use a HashAlgorithm to generate a key with the specific length from the user-input.
Also see: java-aes-and-using-my-own-key