2014-12-01 163 views
1

我認爲這是一個256位密鑰散列,不知道這是否產生256位密文。使用256位密鑰是否意味着密碼會生成256位密文?由此產生的密文是基於64編碼的。這是否使用256位AES加密?

謝謝!

import java.security.spec.InvalidKeySpecException; 
import java.security.InvalidAlgorithmParameterException; 
import java.security.InvalidKeyException; 
import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 
import java.util.Arrays; 

import javax.crypto.Cipher; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 
import javax.crypto.BadPaddingException; 
import javax.crypto.IllegalBlockSizeException; 
import javax.crypto.NoSuchPaddingException; 

import com.ibm.broker.javacompute.Base64; 

public class Security { 
    private static final String AES_PASS = "43qyu3qwjaw8ga5azbro00ig"; // Hashed into an AES key later 
    private SecretKeySpec keyObj; 
    private Cipher cipher; 
    private IvParameterSpec ivObj; 

    public Security() throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException { 
     // A constant IV, since CBC requires an IV but we don't really need one 
     byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 
     this.ivObj = new IvParameterSpec(iv); 

     // Create an SHA-256 256-bit hash of the key 
     byte[] key = AES_PASS.getBytes(); 
     MessageDigest sha = MessageDigest.getInstance("SHA-256"); 
     key = sha.digest(key); 
     key = Arrays.copyOf(key, 32); // Use only first 256 bit 
     this.keyObj = new SecretKeySpec(key, "AES"); 

     // Create a Cipher by specifying the following parameters 
     // a. Algorithm name - here it is AES 
     // b. Mode - here it is CBC mode 
     // c. Padding - e.g. PKCS7 or PKCS5 
     this.cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); 
    } 

    public String encrypt(String strDataToEncrypt) throws InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, NoSuchPaddingException { 
     String strCipherText = new String(); 

     this.cipher.init(Cipher.ENCRYPT_MODE, this.keyObj, this.ivObj); 

     // Encrypt the Data 
     // a. Declare/Initialize the Data. Here the data is of type String 
     // b. Convert the Input Text to Bytes 
     // c. Encrypt the bytes using doFinal method 
     byte[] byteDataToEncrypt = strDataToEncrypt.getBytes(); 

     byte[] byteCipherText = this.cipher.doFinal(byteDataToEncrypt); 

     // b64 is done differently on Android 
     strCipherText = Base64.encode(byteCipherText); 

     return strCipherText; 
    } 

    public String decrypt(String strCipherText) throws InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, NoSuchPaddingException { 
     String strDecryptedText = new String(); 

     // Initialize the Cipher for Encryption 
     this.cipher.init(Cipher.DECRYPT_MODE, this.keyObj, this.ivObj); 

     // Decode the Base64 text 
     byte[] cipherBytes = Base64.decode(strCipherText); 

     // Decrypt the Data 
     // a. Initialize a new instance of Cipher for Decryption (normally don't reuse the same object) 
     //  Be sure to obtain the same IV bytes for CBC mode. 
     // b. Decrypt the cipher bytes using doFinal method 
     byte[] byteDecryptedText = this.cipher.doFinal(cipherBytes); 
     strDecryptedText = new String(byteDecryptedText); 

     return strDecryptedText; 
    } 
} 

回答

2

您的示例似乎使用32位密鑰和256位版本的AES密碼系統。所以,從技術上講,它是256位AES加密。消息的實際大小決定了結果輸出,但它應該大於原始消息。此外,你應該能夠解密它並獲得原始信息。最後,建議使用常量iv的是而不是,並且可能使您的系統本身不安全。

+0

它看起來像基地64編碼的字符串只有160位。但由於密鑰是256位,這仍被認爲是256位AES加密? – Wes 2014-12-01 20:01:51

+0

@Wes這是一條短消息,但是如果密鑰更長,那麼可能的消息是。這是確定加密類型的關鍵和算法(**不是**消息)。 – 2014-12-01 20:04:18

+0

至於常數IV,我們使用的是永不改變的全局加密密鑰(應用程序不會使用會話或登錄),因此IV對於此處的應用程序似乎沒有意義。由於該算法需要一個,而不是不提供IV我只是提供一個恆定的。 – Wes 2014-12-01 20:08:31

0
MessageDigest sha = MessageDigest.getInstance("SHA-256"); 
key = sha.digest(key); 

以下代碼創建一個輸入的哈希鍵,它是關鍵字。如果我們有一些數據「x」和「y」,除非x = y「x」的散列永遠不會等於「y」的散列,這可以用來確定原始數據是否被篡改,因爲如果它會產生一個不同的散列。

key = Arrays.copyOf(key, 32); // Use only first 256 bit 
this.keyObj = new SecretKeySpec(key, "AES"); 

在這種情況下你得到32個字節的摘要的創建並形成祕密密鑰是大小爲256位爲8X32 = 256 您然後使用該密碼與此鍵進行加密和沿解密。

大部分密碼都是以塊的形式運行的(這個是這樣做的)。他們將要加密的文本劃分爲與密鑰大小相同的固定塊大小,然後對該塊應用XOR等操作以獲得加密塊。如果文本大小與密碼塊大小不一致,則會在文本上附加額外的填充以將其與固定塊大小對齊。

+0

不,每次AES塊大小爲128位,但密鑰大小可能在128位,192位和256位之間變化。您可能意指的是Rijndael,它也支持256位塊大小。 – 2014-12-01 20:27:55

+0

你是正確的AES/CBC/PKCS5Padding(128)「https://docs.oracle.com/javase/7/docs/api/javax/crypto/Cipher.html」。但我認爲答案已經清除了許多關於這個問題的疑問。 – Manish 2014-12-01 21:40:00

+0

在上面的代碼中,您使用「SHA-256」創建加密密鑰,但稍後再將該密鑰與「AES」加密算法相關聯。這是不正確的,與該密鑰關聯的算法應該是「SHA-256」而不是「AES」。 – user2213684 2016-10-28 02:04:04