java - 加密网络应用程序的安全方法

标签 java security aes rsa netty

好吧,我想知道我当前加密网络连接的方法(将在接下来的几行中解释)是否安全且有效。

此外,我还试图记住,我希望使用尽可能少的字节(传输),因为这可能用于 Android。

我当前的方法是使用两种加密方法:RSA(keysize= 512) 和 AES(keysize= 128)

我所做的是:

  1. 服务器生成 RSA 公钥和私钥。
  2. 当客户端连接时,服务器会将 RSA 公钥发送给客户端。
  3. 客户端生成 AES key ,并使用服务器提供的公共(public) RSA key 对 AES key 进行加密。
  4. 客户端发送加密的 AES key ,服务器使用 RSA 私钥解密加密的 AES key 。

现在,如果我是正确的,则不可能从客户端嗅探任何数据包,因为您不可能解密 AES key (无私钥)。

这是一种安全的方式吗?或者是否存在某种后门?

但这不是我唯一的问题;

因为我的应用程序是用 Java 构建的,所以总是可以对其进行逆向工程。既然客户端生成了AES Key并保存在内存中,那么是否可以获取到AES Key呢?

最后一个问题: 使用以下代码生成 key 对大约需要 300 毫秒:

我希望得到你们的意见和/或改进。

private RSAKeySet(RSAPublicKey publicKey, PrivateKey privateKey) {
    this.publicKey = publicKey;
    this.privateKey = privateKey;

    byte[] mod = publicKey.getModulus().toByteArray();
    byte[] exp = publicKey.getPublicExponent().toByteArray();

    localPublicKeySpec = ByteBuffer.allocate(mod.length + exp.length + 8);
    localPublicKeySpec.putInt(mod.length);
    localPublicKeySpec.put(mod);
    localPublicKeySpec.putInt(exp.length);
    localPublicKeySpec.put(exp);
    localPublicKeySpec.flip();
}

public static final RSAKeySet generateKeys(int keySize) throws GeneralSecurityException {
    RSAKeySet set;
    long start = System.currentTimeMillis();
    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");

    kpg.initialize(keySize);
    KeyPair kp = kpg.genKeyPair();
    set = new RSAKeySet((RSAPublicKey) kp.getPublic(), kp.getPrivate());

    System.err.println("RSA keys generated (" + (System.currentTimeMillis() - start) + "ms)");
    return set;
}

我正在使用 Netty,300ms 可以承受吗?

提前致谢。

最佳答案

不,这不安全 - 你的方案在第 1 步就被破坏了,因为你无法保证你收到的公钥是由服务器生成的,还是由中间人拦截生成的流量并在将数据发送到真实服务器之前窃听或更改数据。

第二个问题是 512 位 RSA key 太小,不安全。一台现代台式电脑可以在不到一个月的时间内分解这样的 key ,而使用多台计算机可能会缩短到几天/几小时。当您每次生成新 key 时,如果有人只需要窃听连接,他们仍然可以轻松记录流量,然后将 key 离线。

关于访问内存中的 AES key ,是的,这是完全可能的,但是任何有权访问客户端进程内存的人也都可以在加密之前访问明文数据。无论使用哪种特定的加密方法,这都会成为一个问题,尽管确保 key 不会在超出其使用期限后保留在内存中将限制此类攻击可能发生的时间。然而,这在 Java 之类的东西中实现起来要困难一些,因为在 Java 中,即使您在使用后将 key 数据清零,GC 也可能会移动数据并在内存中留下 key 的多个副本。

总之,我强烈建议您不要尝试发明自己的加密方案,而应使用现有的、成熟且经过验证的方案,例如 SSL。我的专业知识不是 Java,但我非常确定 API 中存在建立 SSL session 的方法。

关于java - 加密网络应用程序的安全方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23988164/

相关文章:

linux - Google 搜索安全顾问

java - JProgressBar 上的自定义画家

java - 为什么 Oozie 在运行 MapReduce 作业时分配更多内存?

java - Eclipse Jetty 集成 start.ini

java - 如何运行测试而不在 IE/Chrome WebDriver 的 Action 类中传递本地相对路径,并仅使用 pom 文件中的 Maven 依赖项运行

java - NodeJs使用pbkdf2Sync加密并在java中解密

java - 使用 JDK 7u7 构建的 Applet,在安装的 JRE 7u72 上运行 - 两者之间是否存在安全问题风险?

c++ - 堆溢出的危险?

java - SlowAES加密和java解密

Iphone:如何验证消息验证码(Mac)