2011-12-11 111 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