好的,我想知道我目前加密网络连接的方法(将在接下来的几行中解释)是安全有效的。
此外,我还要记住,我希望尽可能少地使用字节(传输),因为这可能会用于Android。
我目前的方法是使用两种加密方法:RSA(keysize = 512)和AES(keysize = 128)
我做的是:
现在,如果我是正确的,则无法从客户端嗅探任何数据包,因为您无法解密AES密钥(无私钥)。
这是一种安全的方式吗?或者某处有某种后门?
这不是我唯一的问题;
因为我的应用程序是用Java构建的,所以总是可以对它进行逆向工程。由于客户端生成AES密钥并将其保存在内存中,是否可以获取AES密钥?
最后的问题: 使用此代码生成密钥对需要大约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,价格是300毫秒吗?
提前致谢。
答案 0 :(得分:4)
不,这不安全 - 您的方案在步骤#1中被破坏,因为您无法保证您收到的公钥是由服务器生成的,也可能是由中间人拦截流量和窃听,或在将数据发送到真实服务器之前更改数据。
第二个问题是512位RSA密钥太小而不安全。单个现代台式PC可以在不到一个月的时间内考虑到这样的密钥,并且多台机器可能会降低到数天/小时。虽然您每次都会生成一个新密钥,但是有人仍然可以轻松记录流量,然后如果他们只需要窃听连接就会使密钥脱机。
关于在内存中访问AES密钥,是的,这是完全可能的,但是任何有权访问客户端进程内存的人也可以在加密之前访问明文数据。无论使用何种特定的加密方法,这都是一个问题,尽管确保密钥在使用期限之后不会在内存中持续存在,这将限制可能发生此类攻击的时间段。然而,在诸如Java之类的东西中,这有点难以实现,其中GC可以移动数据并在存储器中留下密钥的多个副本,即使您在使用后将密钥数据归零也是如此。
总之,我强烈建议您不要尝试发明自己的加密方案,而是使用现有的,完善的,经过验证的方案,例如SSL。我的专长不是Java,但我很确定在API中存在建立SSL会话的方法。