2016-06-19 13 views
-1

私は、RSA-AESを用いたハイブリッド暗号を作成しようとしたが、今の私は、この符号化で問題に直面しています。このコードから私はRSAキーペア、プライベートキーと公開キーを作成しようとしています。その後、私はAESキーを使ってテキスト文字列を暗号化するためにAES暗号を作成する必要があるランダムなキー対称アルゴリズムAESを生成する必要があります。テキストはAESキーで暗号化された後、その後、AESキーは、RSA公開鍵と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] 1が持っているJavaの内の1つのコードRSAは、多くの場所で「のBigInteger」を使用する方法を見るのは興味深いです。 PythonのようなPLでは、巨大な整数を持つ演算子は小さなものと似ているので、プログラマにとってより便利です。 (私のRSAコードs13.zetaboards.com/Crypto/topic/7234475/1/を参照) –

+0

一般的なアドバイス:**常に完全な暗号文字列を使用する** 'Cipher.getInstance(" RSA ");'結果デフォルトのセキュリティプロバイダに応じて異なる暗号で現在、デフォルトのPKCS#1 v1.5パディングの代わりにOAEPを使用する必要があります。したがって、おそらく 'Cipher.getInstance(" RSA/ECB/OAEPWithSHA-256AndMGF1Padding ");' –

+0

一般的なアドバイス:**必ず完全な暗号文字列を使用してください。** 'Cipher.getInstance(" AES ");' mayデフォルトのセキュリティプロバイダに応じて異なる暗号が生成されます。おそらく '' AES/ECB/PKCS5Padding ''という結果になるでしょうが、必ずしもそうである必要はありません。変更すると、異なるJVM間の互換性が失われます。 –

答えて

0

あなたはこのコードを持って:あなたはnullに初期化されますバッファーで暗号化しようとし

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

を...それができません。

例外

は非常に明確である:

java.lang.IllegalArgumentException: Null input buffer