混合RSA-AES加密

时间:2016-06-19 10:08:39

标签: java encryption aes rsa hybrid

我尝试使用RSA-AES创建混合加密,但是现在我在这个编码中遇到了问题。从这段代码我尝试创建一个RSA密钥对,私钥和公钥。之后,我应该生成随机密钥对称算法AES,然后我必须创建一个AES密码,以便使用AES密钥加密文本字符串。然后在使用AES密钥加密文本之后,需要使用RSA公钥加密AES密钥,并且需要使用RSA私钥解密加密的AES密钥。最后解密用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)

1 个答案:

答案 0 :(得分:0)

您有以下代码:

Where

您尝试使用初始化为null的缓冲区进行加密。这是不可能的。

异常非常清楚:

this.WhenAnyValue(x => x.IsPowered)
    .Where(isPowered => isPowered) // execute only if the passed parameter is true
    .Subscribe(isPowered => 
        {
            await MyService.UpdatePowerStatusAsync(isPowered);
        });