从RSA编码的AES密钥生成AES密钥

我想要做的是使用AES加密字符串,使用RSA加密AES密钥getEncoded()的值,然后解密该AES getEncoded()值,以便获得我的原始串。公钥从用户证书中加载,私钥从文件中加载。代码如下。从RSA编码的AES密钥生成AES密钥

public class Main { 

public static void main(String[] args) throws Exception {

String myString = "My Message";

KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");

keyGenerator.init(128);

SecretKey secretKey = keyGenerator.generateKey();

byte[] initializationVector = new byte[128/8];//16

SecureRandom prng = new SecureRandom();

prng.nextBytes(initializationVector);

Cipher AESCipherForEncryption = Cipher.getInstance("AES/CBC/PKCS5PADDING");

AESCipherForEncryption.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(initializationVector));

byte[] byteVersionOfMyMessage = myString.getBytes();

byte[] byteVersionOfCipherText = AESCipherForEncryption.doFinal(byteVersionOfMyMessage);

String cipherText = new BASE64Encoder().encode(byteVersionOfCipherText);

InputStream in1 = new FileInputStream("user.crt");

CertificateFactory cf1 = CertificateFactory.getInstance("X509");

Certificate c1 = cf1.generateCertificate(in1);

X509Certificate toSendcert = (X509Certificate) c1;

PublicKey publicKey = toSendcert.getPublicKey();

String cipherTextRSA = encryptRSA(publicKey, new String(secretKey.getEncoded()));

String decypheredRSA = decryptRSA(getPrivateKey("user.pk8", "RSA"), cipherTextRSA);

System.out.println(cipherTextRSA);

System.out.println(decypheredRSA);

SecretKey originalKey = new SecretKeySpec(new String(decypheredRSA.getBytes("UTF-8")).getBytes(), 0, new String(decypheredRSA.getBytes("UTF-8")).getBytes().length, "AES");

Cipher AESCipherForDecryption = Cipher.getInstance("AES/CBC/PKCS5PADDING");

AESCipherForDecryption.init(Cipher.DECRYPT_MODE, originalKey, new IvParameterSpec(initializationVector));

byte[] byteVersionOfDecriptedText = AESCipherForDecryption.doFinal(new BASE64Decoder().decodeBuffer(cipherText));

String decMessage = new String(byteVersionOfDecriptedText);

System.out.println(decMessage);

}

public static String encryptRSA(PublicKey pubKey, String message) throws Exception {

Cipher cipher = Cipher.getInstance("RSA");

cipher.init(Cipher.ENCRYPT_MODE, pubKey);

Base64.Encoder encoder = Base64.getEncoder();

String encryptedString = encoder.encodeToString(cipher.doFinal(message.getBytes("UTF-8")));

return encryptedString;

}

public static PrivateKey getPrivateKey(String filename, String algorithm) throws Exception {

File f = new File(filename);

FileInputStream fis = new FileInputStream(f);

DataInputStream dis = new DataInputStream(fis);

byte[] keyBytes = new byte[(int) f.length()];

dis.readFully(keyBytes);

dis.close();

String temp = new String(keyBytes);

String privKeyPEM = temp.replace("-----BEGIN PRIVATE KEY-----", "");

privKeyPEM = privKeyPEM.replace("-----END PRIVATE KEY-----", "");

privKeyPEM = privKeyPEM.replace("\n", "");

byte[] decoded = Base64.getDecoder().decode(privKeyPEM);

PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decoded);

KeyFactory kf = KeyFactory.getInstance(algorithm);

return kf.generatePrivate(spec);

}

public static String decryptRSA(PrivateKey prKey, String encrypted) throws Exception {

Base64.Decoder decoder = Base64.getDecoder();

byte[] input = decoder.decode(encrypted);

Cipher cipher = Cipher.getInstance("RSA");

cipher.init(Cipher.DECRYPT_MODE, prKey);

return new String(cipher.doFinal(input));

}

,我不断收到的错误是:

Exception in thread "main" java.security.InvalidKeyException: Invalid AES key length: 28 bytes 

at com.sun.crypto.provider.AESCipher.engineGetKeySize(AESCipher.java:509)

at javax.crypto.Cipher.passCryptoPermCheck(Cipher.java:1067)

at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1038)

at javax.crypto.Cipher.implInit(Cipher.java:805)

at javax.crypto.Cipher.chooseProvider(Cipher.java:864)

at javax.crypto.Cipher.init(Cipher.java:1396)

at javax.crypto.Cipher.init(Cipher.java:1327)

at com.company.Main.main(Main.java:79)

如果我不加密和解密secretKey.getEncoded()值,只需使用AES没有RSA能够正常工作。同样与RSA合作,如果我只用一个公钥加密一些字符串,并用私有密钥解密它就行。我的问题是:“如何使用RSA正确加密和解​​密secretKey.getEncoded()值,以便我可以正确加密和解​​密myString?”。

回答:

new String(secretKey.getEncoded()) 

这不会工作,因为AES密钥包含随机字节,并不是每个字节都是字符代表。 Java中标准字符串转换的问题是它会丢弃未知字符和字节,而不是在编码/解码期间生成异常。

RSA对字节进行操作,不应将密钥转换为字符串,然后再转换回字节,因为转换可能是有损的(例如,丢失32字节中的4个)。

另外 - 也许更好 - 你可能想尝试密码的包装模式。这应该与那里的一些硬件解决方案兼容。在这种情况下,你甚至不需要拨打getEncoded


OAEP加密和认证的加密模式,例如GCM应在PKCS#1填充(默认为Sun提供者)和CBC模式的加密是优选的。

以上是 从RSA编码的AES密钥生成AES密钥 的全部内容, 来源链接: utcz.com/qa/262583.html

回到顶部