2016-06-19 110 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