2016-06-19 6 views
-1

Я пытаюсь создать гибридное шифрование с использованием RSA-AES, но пока я сталкиваюсь с проблемой в этой кодировке. Из этого кода я пытаюсь создать пару ключей RSA, закрытый и открытый ключ. После этого я должен создать симметричный алгоритм случайного ключа AES, тогда мне нужно создать AES-шифр, чтобы зашифровать текстовую строку с помощью ключа AES. Затем после того, как текст зашифрован с помощью ключа AES, тогда ключ AES должен быть зашифрован открытым ключом RSA, а зашифрованный ключ AES необходимо дешифровать с помощью закрытого ключа RSA. И, наконец, расшифруйте текстовое сообщение, введенное с помощью ключа 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» на многих местах. В PL, таких как Python, операторы с огромными целыми числами похожи на маленькие, что более удобно для программистов. (см. мой код RSA s13.zetaboards.com/Crypto/topic/7234475/1/) –

+0

Общие рекомендации: ** Всегда используйте полностью исписанную строку Cipher. ** '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 

 Смежные вопросы

  • Нет связанных вопросов^_^