2015-11-04 162 views
0

我仍在尋找我的加密需求的一個很好的解決方案。我在互聯網上找到了一個解決方案,我重新編寫了適合程序需求的解決方案,但加密失敗。我不知道爲什麼。有什麼建議麼?

親愛的Maarten Bodeswes我試過你的解決方案,但無法讓它工作穩定。我通過php發送加密的數據到數據庫,並通過php返回。我想我必須用別的東西交換加號,但它仍然不能穩定運行。用AES加密的AES/CBC/PKCS5Padding不起作用

import java.io.IOException; 
import java.security.InvalidAlgorithmParameterException; 
import java.security.InvalidKeyException; 
import java.security.NoSuchAlgorithmException; 
import java.security.SecureRandom; 
import java.security.spec.InvalidKeySpecException; 
import java.security.spec.InvalidParameterSpecException; 
import java.security.spec.KeySpec; 
import java.util.Random; 
import javax.crypto.BadPaddingException; 
import javax.crypto.Cipher; 
import javax.crypto.IllegalBlockSizeException; 
import javax.crypto.NoSuchPaddingException; 
import javax.crypto.SecretKey; 
import javax.crypto.SecretKeyFactory; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.PBEKeySpec; 

public class AESplus 
{ 

// AES specification 
private static final String CIPHER_SPEC = "AES/CBC/PKCS5Padding"; 

// Key derivation specification 
private static final String KEYGEN_SPEC = "PBKDF2WithHmacSHA1"; 
private static final int SALT_LENGTH = 16; // in bytes 
private static final int ITERATIONS = 32768; 
private static final int KEY_LENGTH = 128; 

private static final String SPLITCHAR = "###"; 

public static SecretKey makeKey(String kennwort) throws NoSuchAlgorithmException, InvalidKeySpecException 
{ 
    char[] password = kennwort.toCharArray(); 

    // generate salt 
    byte[] salt = generateSalt(SALT_LENGTH); 

    SecretKeyFactory factory = SecretKeyFactory.getInstance(KEYGEN_SPEC); 

    KeySpec spec = new PBEKeySpec(password, salt, ITERATIONS, KEY_LENGTH); 
    SecretKey tmp = factory.generateSecret(spec); 

    return tmp; 
} 

private static byte[] generateSalt(int length) 
{ 
    Random r = new SecureRandom(); 
    byte[] salt = new byte[length]; 
    r.nextBytes(salt); 
    return salt; 
} 

public static String encrypt(String input, SecretKey key) throws InvalidKeyLengthException, StrongEncryptionNotAvailableException, 
         IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidParameterSpecException, 
         IllegalBlockSizeException, BadPaddingException 
{ 
    StringBuilder output = new StringBuilder(); 

    // initialize AES encryption 
    Cipher encrypt = null; 
    encrypt = Cipher.getInstance(CIPHER_SPEC); 
    encrypt.init(Cipher.ENCRYPT_MODE, key); 

    // get initialization vector 
    byte[] iv = encrypt.getParameters().getParameterSpec(IvParameterSpec.class).getIV(); 

    byte[] encrypted = encrypt.update(input.getBytes()); 
    output.append(HexUtils.toHex(encrypted)); 

    encrypted = encrypt.doFinal(); 

    if (encrypted != null) 
    { 
     // write authentication and AES initialization data 
     output.append(HexUtils.toHex(iv) + SPLITCHAR); 
     // data 
     output.append(HexUtils.toHex(encrypted)); 
    } 

    return output.toString(); 
} 

public static String decrypt(String input, SecretKey schlüssel) throws InvalidPasswordException, InvalidAESStreamException, 
         IOException, StrongEncryptionNotAvailableException, NoSuchAlgorithmException, NoSuchPaddingException, 
         InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException 
{ 
    String[] inputArray = input.split(SPLITCHAR); 

    // initialize AES decryption 
    byte[] iv = new byte[16]; // 16-byte I.V. regardless of key size 
    iv = HexUtils.toBytes(inputArray[0]); 

    Cipher decrypt = Cipher.getInstance(CIPHER_SPEC); 
    decrypt.init(Cipher.DECRYPT_MODE, schlüssel, new IvParameterSpec(iv)); 

    // read data from input into buffer, decrypt and write to output 
    byte[] hexInput = HexUtils.toBytes(inputArray[1]); 
    byte[] decrypted = decrypt.update(hexInput); 

    StringBuilder output = new StringBuilder(); 
    output.append(new String(decrypted)); 

    // finish decryption - do final block 
    decrypted = decrypt.doFinal(); 
    if (decrypted != null) 
    { 
     output.append(new String(decrypted)); 
    } 

    return output.toString(); 
} 


// ******** EXCEPTIONS thrown by encrypt and decrypt ******** 

/** 
* Thrown if an attempt is made to decrypt a stream with an incorrect 
* password. 
*/ 
public static class InvalidPasswordException extends Exception 
{ 
    private static final long serialVersionUID = 1L; 
} 

/** 
* Thrown if an attempt is made to encrypt a stream with an invalid AES key 
* length. 
*/ 
public static class InvalidKeyLengthException extends Exception 
{ 
    private static final long serialVersionUID = 1L; 

    InvalidKeyLengthException(int length) 
    { 
     super("Invalid AES key length: " + length); 
    } 
} 

/** 
* Thrown if 192- or 256-bit AES encryption or decryption is attempted, 
* but not available on the particular Java platform. 
*/ 
public static class StrongEncryptionNotAvailableException extends Exception 
{ 
    private static final long serialVersionUID = 1L; 

    public StrongEncryptionNotAvailableException(int keySize) 
    { 
     super(keySize + "-bit AES encryption is not available on this Java platform."); 
    } 
} 

/** 
* Thrown if an attempt is made to decrypt an invalid AES stream. 
*/ 
public static class InvalidAESStreamException extends Exception 
{ 
    private static final long serialVersionUID = 1L; 

    public InvalidAESStreamException() 
    { 
     super(); 
    }; 

    public InvalidAESStreamException(Exception e) 
    { 
     super(e); 
    } 
} 
} 
+0

查看我的回答[here](http://stackoverflow.com/a/33187333/4405473)。希望這可以幫助。 – k170

回答

1

這塊代碼的放四到輸出的中間:

byte[] encrypted = encrypt.update(input.getBytes()); 
output.append(HexUtils.toHex(encrypted)); 
encrypted = encrypt.doFinal(); 

if (encrypted != null) 
{ 
    // write authentication and AES initialization data 
    output.append(HexUtils.toHex(iv) + SPLITCHAR); 
    // data 
    output.append(HexUtils.toHex(encrypted)); 
} 

當您解密方法工作,它需要在開始。