我不是这方面的专家,所以我需要听从专家的意见。以下示例是加密和解密消息(长度未知)以在潜在不安全的网络(即电子邮件、HTTP 请求或其他方式)中传输的相当安全的方法吗?我所说的“相当安全”是指,可以防止临时或半确定的第三方阅读该消息。
使用随机 AES key 加密消息,并通过使用公钥加密来保护 AES key 。
public static String encrypt(String data, PublicKey publicKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
// Create AES secret key
Cipher aes = Cipher.getInstance("AES");
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(256);
SecretKey key = kgen.generateKey();
SecretKeySpec aeskeySpec = new SecretKeySpec(key.getEncoded(), "AES");
// Encrypt data with AES Secret key
aes.init(Cipher.ENCRYPT_MODE, aeskeySpec);
byte[] dataEncoded = aes.doFinal(data.getBytes());
// Encrypt the secret AES key with the public key
Cipher rsa = Cipher.getInstance("RSA");
rsa.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] aesKeyEncoded = rsa.doFinal(key.getEncoded());
// Output both secret AES key and data
return
Base64.getEncoder().encodeToString(aesKeyEncoded) + "~" +
Base64.getEncoder().encodeToString(dataEncoded);
}
解密 AES key ,然后解密消息:
public static String decrypt(String data, PrivateKey privateKey) throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException {
String[] parts = data.split("~");
// Decrypt AES secret key
byte[] encodedSecretKey = Base64.getDecoder().decode(parts[0]);
Cipher rsa = Cipher.getInstance("RSA");
rsa.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decodedSecretKey = rsa.doFinal(encodedSecretKey);
SecretKeySpec key = new SecretKeySpec(decodedSecretKey, "AES");
// Decrypt message
Cipher aes = Cipher.getInstance("AES");
aes.init(Cipher.DECRYPT_MODE, key);
byte[] decodedData = aes.doFinal(Base64.getDecoder().decode(parts[1]));
return new String(decodedData);
}
使用上述方法:
public static void main(String args[]) throws NoSuchAlgorithmException, BadPaddingException, NoSuchPaddingException, IllegalBlockSizeException, InvalidKeyException {
// Generate public/private key
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(2048, new SecureRandom());
KeyPair kp = generator.generateKeyPair();
System.out.println(" Public key = " + Base64.getEncoder().encodeToString(kp.getPublic().getEncoded()));
System.out.println("Private key = " + Base64.getEncoder().encodeToString(kp.getPrivate().getEncoded()));
String mytext = "test message with some test data.";
String e = encrypt(mytext, kp.getPublic());
String d = decrypt(e, kp.getPrivate());
System.out.println(" text = " + mytext);
System.out.println("Decoded text = " + d);
}
最佳答案
只要您可以信任 RSA 公钥,总体思路就可以。如果只是将公钥发送给对方,则不是。
您还需要通过添加完整性和真实性来保护您的密文。您可以通过切换到 AES/GCM 模式(仅在 Java 8 中可用,或使用 Bouncy CaSTLe)轻松完成此操作。目前您正在使用不安全的 AES/ECB 加密模式。
您应该尝试使用带有 OAEP 填充的 RSA,而不是 PKCS#1 v1.5 填充。一般来说,您不应依赖默认字符编码 (getBytes()
) 或密码模式。
所以最后:不,那不安全。如果您想避免许多陷阱,请尝试使用 TLS。
关于java - 这是使用 java 加密(使用公钥)可能通过不安全网络发送的消息的安全方法吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24401786/