2016-06-19 142 views
-1

我嘗試使用RSA-AES創建混合加密,但現在我面臨這種編碼中的問題。從這個代碼我嘗試創建一個RSA密鑰對,私鑰和公鑰。之後,我應該生成一個隨機密鑰對稱算法AES然後我必須創建一個AES密碼,以便用AES密鑰加密一個文本字符串。然後在用AES密鑰加密文本後,需要使用RSA公鑰對AES密鑰進行加密,並且需要使用RSA私鑰對加密的AES密鑰進行解密。最後,用AES密鑰解密輸入的文本消息,以便讀取消息。我想我在編碼中錯過了一些東西。請幫助我們。混合RSA-AES加密

import java.math.BigInteger; 
    import java.security.InvalidKeyException; 
    import java.security.Key; 
    import java.security.KeyFactory; 
    import java.security.KeyPair; 
    import java.security.KeyPairGenerator; 
    import java.security.NoSuchAlgorithmException; 
    import java.security.PrivateKey; 
    import java.security.PublicKey; 
    import java.security.SecureRandom; 
    import java.security.Security; 
    import java.security.spec.EncodedKeySpec; 
    import java.security.spec.InvalidKeySpecException; 
    import java.security.spec.X509EncodedKeySpec; 
    import java.util.logging.Level; 
    import java.util.logging.Logger; 
    import javax.crypto.Cipher; 
    import javax.crypto.KeyGenerator; 
    import javax.crypto.NoSuchPaddingException; 
    import javax.crypto.SecretKey; 

    import org.bouncycastle.jce.provider.BouncyCastleProvider; 

    import sun.misc.BASE64Decoder; 
    import sun.misc.BASE64Encoder; 

    public class HybridAesRsa 
    { 

     private Cipher cipher; 

     // RSA keys will be generated when the client and server connect 
     private PrivateKey myPrivateKey; 
     private byte[] myPublicKey; 
     private byte[] interlocutorPublicKey = null; 

     // Strings are encoded/decoded in BASE64 
     private BASE64Decoder b64decoder = new BASE64Decoder(); 
     private BASE64Encoder b64encoder = new BASE64Encoder(); 

     public HybridAesRsa() 
     { 
     try 
     { 
     cipher = Cipher.getInstance("RSA"); 
     Security.addProvider(new BouncyCastleProvider()); 
     } 

     catch (Exception ex){ 
        Logger.getLogger(HybridAesRsa.class.getName()).log(Level.SEVERE,null,ex); 
     } 
     } 

    // Generate the pair of public and private keys using 1024 bytes 
    public KeyPair generateKey() throws Exception 
    { 
     KeyPair keyPair = null; 

     try{ 
     //generate RSA key pair 
     KeyPairGenerator rsaKeyGen = KeyPairGenerator.getInstance("RSA"); 
     rsaKeyGen.initialize(1024); 
     keyPair = rsaKeyGen.generateKeyPair(); 

     //RSA public and private key 
     PublicKey publicKey = keyPair.getPublic(); 
     PrivateKey privateKey = keyPair.getPrivate(); 
     //System.out.println("RSA public key 1 ---> "+publicKey); 
     //System.out.println("RSA private key 1 ---> " +privateKey); 

     //for Chatting 
     myPublicKey = publicKey.getEncoded(); 
     setMyPrivateKey(privateKey); 

     //Generating a random key symmetrical algorithm AES 
     KeyGenerator aesKeyGenerator = KeyGenerator.getInstance("AES"); 
     SecureRandom random = new SecureRandom(); 
     aesKeyGenerator.init(random);   
     SecretKey aesSecretKey = aesKeyGenerator.generateKey(); 

     /*//The key is presented in a byte array   
     byte[] symmetricKey = aesSecretKey.getEncoded(); 

     //Printing out the generated key  
     System.out.println("\nAES symmetric key --> " + symmetricKey); */  

     } catch (NoSuchAlgorithmException ex) { 
      Logger.getLogger(HybridAesRsa.class.getName()).log(Level.SEVERE,null,ex); 
    } 
    return keyPair; 
    } 

    // Encrypts text using public key 
    public String encrypt(String text, PublicKey publicKey, SecretKey aesSecretKey) throws Exception 
{ 
    //Creating an AES cipher in order to encrypt a text string with the AES key 
    Cipher aesCipher = Cipher.getInstance("AES"); 
    aesCipher.init(Cipher.ENCRYPT_MODE, aesSecretKey); 

    //Now that the text is encrypted with the AES key, then the AES key needs to be encrypted with the RSA public key 
    Cipher rsaCipher = Cipher.getInstance("RSA"); 
    rsaCipher.init(Cipher.ENCRYPT_MODE, publicKey); 

    byte[] encryptedAESkey = rsaCipher.doFinal(aesSecretKey.getEncoded()); 

    //Printing out the encrypted AES key 
    System.out.println("\nAES key encrypted with RSA --> " + encryptedAESkey); 

    return text; 
} 

// Use the public key to encrypt the interlocutor 
public String encrypt(String text) throws Exception 
{ 
    return encrypt(text, bytesToPublicKey(interlocutorPublicKey), null); 
} 

// Decrypts text using private key 
public String decrypt(String text, PrivateKey privatekey) throws Exception 
{ 
    // Now the encrypted AES key needs to be decrypted with the RSA private key 
    Cipher rsaCipher2 = Cipher.getInstance("RSA"); 
    rsaCipher2.init(Cipher.DECRYPT_MODE, privatekey); 
    byte[] encryptedAESkey = null; 
    byte[] decryptedAESkey = rsaCipher2.doFinal(encryptedAESkey); 

    //Print out the decrypted AES key 
    System.out.println("AES key decrypted with RSA private key --> " + decryptedAESkey); 

    //And finally decrypt the text message entered with AES key in order to read the message. 
    Cipher aesCipher2 = Cipher.getInstance("AES"); 

    Key aesSecretKey = null; 
    aesCipher2.init(Cipher.DECRYPT_MODE,aesSecretKey); 

    byte[] encrypt = null; 
    byte [] decrypt = aesCipher2.doFinal(encrypt); 

    return text; 

} 

// Use my private key to decrypt 
public String decrypt(String text) throws Exception 
{ 
    return decrypt(text, myPrivateKey); 
} 

// Public Key the caller is sent in byte [ ] and converted into a PublicKey object 
public static PublicKey bytesToPublicKey(byte[] publicKeybytes) 
{ 
    PublicKey publicKey = null; 

    try { 
     KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
     EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeybytes); 
     publicKey = keyFactory.generatePublic(publicKeySpec); 
    } 

    catch (InvalidKeySpecException ex) { 
     Logger.getLogger(HybridAesRsa.class.getName()).log(Level.SEVERE, null, ex); 
    } 

    catch (NoSuchAlgorithmException ex){ 
     Logger.getLogger(HybridAesRsa.class.getName()).log(Level.SEVERE, null, ex); 
    } 

     return publicKey;  
} 

    // Test 
public static void main(String[] args){ 
    try { 
     HybridAesRsa crypto = new HybridAesRsa(); 
     KeyPair keyPair = crypto.generateKey(); 

     PublicKey publicKey = keyPair.getPublic(); 
     PrivateKey privateKey = keyPair.getPrivate(); 
     KeyGenerator aesKeyGenerator = KeyGenerator.getInstance("AES"); 
     SecretKey aesSecretKey = aesKeyGenerator.generateKey();   

     byte[] publicKeyBytes = publicKey.getEncoded(); 
     byte[] privateKeyBytes = privateKey.getEncoded(); 
     byte[] symmetricKey = aesSecretKey.getEncoded(); 

     System.out.println("RSA Public key: " + new BigInteger(publicKeyBytes)); 
     System.out.println("RSA Private key: " + new BigInteger(privateKeyBytes)); 
     System.out.println("AES symmetric key --> " + new BigInteger(symmetricKey)); 

     Cipher aesCipher = Cipher.getInstance("AES"); 
     aesCipher.init(Cipher.ENCRYPT_MODE, aesSecretKey); 

     String testeMsg = "As a seed knows how to make a flower ? I love you."; 
     byte[] encrypt = aesCipher.doFinal(testeMsg.getBytes()); 

     Cipher rsaCipher = Cipher.getInstance("RSA"); 
     rsaCipher.init(Cipher.ENCRYPT_MODE, publicKey); 
     byte[] encryptedAESkey = rsaCipher.doFinal(aesSecretKey.getEncoded()); 


     String encrypted = crypto.encrypt(testeMsg, bytesToPublicKey(publicKeyBytes), aesSecretKey); 
     System.out.println("Encrypted Text: " + encrypted); 

     String decrypted = crypto.decrypt(encrypted, keyPair.getPrivate());      
     System.out.println("Decrypted Text: " + decrypted); 
    } 

    catch (Exception ex) 
    { 
      Logger.getLogger(HybridAesRsa.class.getName()).log(Level.SEVERE, null, ex); 
    } 

} 

public byte[] getMyPublicKey(){ 
    return myPublicKey; 
} 

public void setMyPublicKey(byte[] myPublicKey) { 
    this.myPublicKey = myPublicKey; 
} 

public PrivateKey getMyPrivateKey(){ 
    return myPrivateKey; 
} 

public byte[] getInterlocutorPublicKey(){ 
    return interlocutorPublicKey; 
} 

public boolean hasInterlocutorPublicKey(){ 
    return interlocutorPublicKey!=null; 
} 

public void setInterlocutorPublicKey(byte[] interlocutorPublicKey){ 
    this.interlocutorPublicKey = interlocutorPublicKey; 
} 

public void setMyPrivateKey(PrivateKey aMyPrivateKey){ 
    myPrivateKey = aMyPrivateKey; 
} 
} 

下面這個代碼中的錯誤

Jun 19, 2016 5:50:14 PM HybridAesRsa main 
    SEVERE: null 
    java.lang.IllegalArgumentException: Null input buffer 
    at javax.crypto.Cipher.doFinal(Cipher.java:2117) 
    at HybridAesRsa.decrypt(HybridAesRsa.java:125) 
    at HybridAesRsa.main(HybridAesRsa.java:204) 
+0

[OT]饒有興趣的看着一個代碼RSA在Java中,其中一個是如何使用「的BigInteger」在很多地方。在像Python這樣的PL中,具有巨大整數的運算符就像小型運算符一樣,因此對程序員來說更方便。 (參見我的RSA代碼s13.zetaboards.com/Crypto/topic/7234475/1/) –

+0

一般建議:**始終使用完全限定的密碼字符串**'Cipher.getInstance(「RSA」);'可能導致取決於默認安全提供程序的不同密碼。現在,您應該使用OAEP而不是默認的PKCS#1 v1.5填充。所以你應該使用Cipher.getInstance(「RSA/ECB/OAEPWithSHA-256AndMGF1Padding」);' –

+0

一般建議:**總是使用完全合格的Cipher字符串**'Cipher.getInstance(「AES」);'可以導致取決於默認安全提供程序的不同密碼。它很可能會導致''AES/ECB/PKCS5Padding'',但它不一定是。如果它改變,你將失去不同JVM之間的兼容性。 –

回答

0

你有這樣的代碼:

byte[] encrypt = null; 
byte [] decrypt = aesCipher2.doFinal(encrypt); 

在您嘗試與同時初始化爲空..一個緩衝區來加密是不可能的。

唯一的例外是相當清楚的:

java.lang.IllegalArgumentException: Null input buffer