我尝试使用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)
答案 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);
});