2011-12-11 68 views
0

我正在开发一个项目,我需要使用AES加密字符串。该程序需要能够接受一个字符串并输出一个十六进制的加密字符串和一个密钥,或者使用用户指定的密钥和字符串输出未加密的文本(也就是说,程序需要能够在不同的情况下做这两件事情,即我应该能够在我的机器上放置“1234”并出去“加密文本:asdf键:ghjk”;我的朋友应该能够加入“加密文本:asdf KEy :ghjk”他,走出 “1234”)

这是我到目前为止有:

AES加密问题

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? 
    } 

} 
    } 
} 

那么,希望有人能帮助我。

编辑:

我最大的问题是转换字符串encryptedString成sKeySpec并找出如何防止“解密方法”功能从为用户提供一个错误,说字符串输入他们没有正确填充。我知道这是不正确的,因为我已经试过对字符串进行加密,然后将它的加密形式粘贴到非加密器中,只是为了得到错误。如果我消除所有的“if”条件,并且只需要加密一个字符串,然后在同一个实例中解密它,该程序就可以正常工作;我认为,这是由于凯基的随机密钥的保存

+2

您可以编辑您的问题具体解决你在哪里停留?从代码中的评论中推导出你的问题有点难。 – Alan

回答

0

你的问题是这样的:

KeyGenerator kgen = KeyGenerator.getInstance("AES");kgen.init(128); 
SecretKey skey = kgen.generateKey(); 
byte[] bytes = skey.getEncoded(); 
SecretKeySpec skeySpec = new SecretKeySpec(bytes, "AES"); 

当你写它,你的程序生成一个新的随机密钥每一次它的运行,这从未保存或显示在任何地方。任何你用这个密钥加密的东西实际上都不可能解密。

你需要做的是提出一些从用户输入生成密钥的方案,而不是使用KeyGenerator随机生成密钥。该计划将如何工作取决于你。

0

根据您使用的AES变体,您的密钥需要长度为128,192或256Bit。 您可以使用HashAlgorithm从用户输入中生成具有特定长度的密钥。

String key; 
byte[] keydata = hashFunctionToMakeToKeytheRightSize(key); 
SecretKeySpec secretKeySpec = new SecretKeySpec(keydata, "AES"); 

另见:java-aes-and-using-my-own-key

+0

“找不到方法:.hasFunctionToMakeToKEytheRightSize” –

+0

http://docs.oracle.com/javase/1.5.0/docs/api/java/security/MessageDigest.html – HectorLector