java.security.InvalidKeyException:密钥长度不是128/192/256位

时间:2011-07-08 14:19:15

标签: java cryptography public-key-encryption encryption encryption-symmetric

我是Java的新手,并尝试使用AES-128对称加密的混合加密技术,然后在生成的对称密钥上使用RSA-1024非对称加密。有人可以帮助我为什么会得到这个例外。我已经关注了其他帖子,并在相应的文件夹中下载了Java Cryptography Extension(JCE)Unlimited Strength Jurisdiction Policy Files第6版。

Code snippet:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.security.Key;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Security;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;

    public class MainClass {

        /**
         * @param args
         * Encryption and Decryption with AES/ECB/PKCS7Padding  and RSA/ECB/PKCS1Padding
         */
        public static void main(String[] args) throws Exception {
            // TODO Auto-generated method stub
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());   
            System.out.println("Enter a Message to be encrypted!");
            // Read an input from console
            InputStreamReader isr = new InputStreamReader(System.in);
            BufferedReader br = new BufferedReader(isr);
            String s = br.readLine();

            // Get the bytes of the input stream. Convert the input text
            // to bytes.
            byte[] input = s.getBytes("UTF8");

            System.out.println("Input Message : " + new String(input));

            // AES 128 bits Symmetric encryption of data

            // Generate the AES key for Symmetric AES encryption
            KeyGenerator kgenerator = KeyGenerator.getInstance("AES", "BC");
            SecureRandom random = new SecureRandom();
            kgenerator.init(128, random);

            Key aeskey = kgenerator.generateKey();
            byte[] raw = aeskey.getEncoded();
            int sykLength = raw.toString().length();
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");

            System.out.println("Generated Symmetric Key :" + raw);
            System.out.println("Generated Symmetric Key Length :" + sykLength);
            System.out.println("Generated Key Length in Bytes: " + raw.length);

            // Encrypt the data using AES cipher
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec);         
            byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
            int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
            ctLength += cipher.doFinal(cipherText, ctLength);

            System.out.println("Encrypted Message :" + new String(cipherText));
            System.out.println("Encrypted Message Length: " + ctLength);

           // RSA 1024 bits Asymmetric encryption of Symmetric AES key

          // Generate Public and Private Keys (Can also use a certificate for keys)
            KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");
            kpg.initialize(1024, random);
            KeyPair kpa = kpg.genKeyPair();
            RSAPublicKey pubKey = (RSAPublicKey) kpa.getPublic();
            RSAPrivateKey privKey = (RSAPrivateKey)kpa.getPrivate();    

          // Encrypt the generated Symmetric AES Key using RSA cipher  
            Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");            
            rsaCipher.init(Cipher.ENCRYPT_MODE, pubKey);            
            byte[] rawRSA = raw.toString().getBytes("UTF8");
            byte[] cipherTextRSA = new byte[rsaCipher.getOutputSize(rawRSA.length)];
            int ctLengthRSA = rsaCipher.update(rawRSA, 0, rawRSA.length, cipherTextRSA, 0);
            ctLengthRSA += rsaCipher.doFinal(cipherTextRSA, ctLengthRSA);

            System.out.println("Encrypted Symmetric Key :" + cipherTextRSA);
            System.out.println("Encrypted Symmetric Key Length :" + ctLengthRSA);
            System.out.println("Encrypted Symmetric Key Length in Bytes: " + cipherTextRSA.length);

            // RSA Decryption of Encrypted Symmetric AES key
            rsaCipher.init(Cipher.DECRYPT_MODE, privKey);
            byte[] plainTextRSA = new byte[rsaCipher.getOutputSize(ctLengthRSA)];
            int ptLengthRSA = rsaCipher.update(cipherTextRSA, 0, ctLengthRSA, plainTextRSA, 0);
            ptLengthRSA += rsaCipher.doFinal(plainTextRSA, ptLengthRSA);
            SecretKeySpec DecrypskeySpec = new SecretKeySpec(plainTextRSA, "AES");  

            System.out.println("Decrypted Symmetric Key: " + new String(plainTextRSA));
            System.out.println("Decrypted Symmetric Key Length: " + ptLengthRSA);       
            System.out.println( "Decrypted Symmetric Key Length in Bytes: " + plainTextRSA.length);

                cipher.init(Cipher.DECRYPT_MODE, DecrypskeySpec, cipher.getParameters());
                byte[] plainText = new byte[cipher.getOutputSize(ctLength)];
                int ptLength = cipher.update(cipherText, 0, ctLength, plainText, 0);
                ptLength += cipher.doFinal(plainText, ptLength);
                System.out.println("Decrypted Message: " + new String(plainText));
                System.out.println("Decrypted Message Length: " + ptLength);
                System.out.println("Decrypted Message Length in Bytes: " + plainText.length);
        }
    }

我得到的例外

Enter a Message to be encrypted!
test
Input Message : test
Generated Symmetric Key :[B@1c74f37
Generated Symmetric Key Length :10
Generated Key Length in Bytes: 16
Encrypted Message :ýÒSœW¶Þ34Ý­GÝ
Encrypted Message Length: 16
Encrypted Symmetric Key :[B@1df280b
Encrypted Symmetric Key Length :128
Encrypted Symmetric Key Length in Bytes: 128
Decrypted Symmetric Key: [B@1c74f37         (Some symbols I got along with this decrypted key which I could not paste here)
Decrypted Symmetric Key Length in Bytes: 117
Exception in thread "main" java.security.InvalidKeyException: Key length not 128/192/256 bits.
    at org.bouncycastle.jce.provider.JCEBlockCipher.engineInit(Unknown Source)
    at org.bouncycastle.jce.provider.JCEBlockCipher.engineInit(Unknown Source)
    at javax.crypto.Cipher.init(DashoA13*..)
    at javax.crypto.Cipher.init(DashoA13*..)
    at com.sap.srm.crpto.client.applet.MainClass.main(MainClass.java:99)

2 个答案:

答案 0 :(得分:9)

实际上你尝试使用非对称RSA包装和打开对称密钥时会出现很多错误,所以我清理了它(我的机器上没有Bouncy Castle,所以我使用了默认的Sun提供商,随意在需要的地方添加“BC”:

KeyGenerator kgenerator = KeyGenerator.getInstance("AES");
SecureRandom random = new SecureRandom();
kgenerator.init(128, random);
Key aeskey = kgenerator.generateKey();

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024, random);
KeyPair kpa = kpg.genKeyPair();
PublicKey pubKey = kpa.getPublic();
PrivateKey privKey = kpa.getPrivate();    

// Encrypt the generated Symmetric AES Key using RSA cipher  
Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");            
rsaCipher.init(Cipher.WRAP_MODE, pubKey);
byte[] encryptedSymmKey = rsaCipher.wrap(aeskey);            
// RSA Decryption of Encrypted Symmetric AES key
rsaCipher.init(Cipher.UNWRAP_MODE, privKey);
Key decryptedKey = rsaCipher.unwrap(encryptedSymmKey, "AES", Cipher.SECRET_KEY);

System.out.println("Decrypted Key Length: " + decryptedKey.getEncoded().length * 8); // -> 128

答案 1 :(得分:0)

不是答案,但在此处更容易格式化代码,为了帮助调试或检查输出,请在缓冲区中使用十六进制转换,然后再将其吐出日志。你可以使用这样的东西。

public static String asHex (byte buf[]) 
{
    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();
   }