java - 这是使用 java 加密(使用公钥)可能通过不安全网络发送的消息的安全方法吗

标签 java encryption cryptography

我不是这方面的专家,所以我需要听从专家的意见。以下示例是加密和解密消息(长度未知)以在潜在不安全的网络(即电子邮件、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/

相关文章:

c# - 我应该为表中的密码字段使用什么? MD5 还是 SHA1?

java - 如何获取 Cipher 的最大 key 大小

java 的 DB.getCollection() 不会创建集合,即使 javadoc 是这样说的

java - 致命异常 : java. lang.UnsupportedOperationException:无法解析索引 6 处的属性:TypedValue{t=0x2/d=0x101009b a=1}

c# - Azure 媒体播放器无法在 iPhone 上使用 AES 保护

database - Oracle 数据库 11g 使用了哪个 PKCS#11 函数?

java - Spring Data JPA 存储库 findAll() 空指针

java - 如何将文件对象类型转换为 InputStream

java - 有没有一种简单的方法来加密java对象?

c# - 在将类保存到 xml 文件之前加密属性