【发布时间】:2016-02-27 09:43:39
【问题描述】:
我希望在运行在 Java RMI 上的客户端和服务器程序之间交换对称密钥。
我的服务器生成了一个公钥:
KeyPairGenerator keyGen = null;
try {
keyGen = KeyPairGenerator.getInstance("DSA", "SUN");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
}
KeyPair pair = keyGen.generateKeyPair();
this.priv = pair.getPrivate();
this.pub = pair.getPublic();
我将公钥发送给客户端。客户端将使用服务器的公钥生成密码。我想使用这个 Cipher 来加密封装客户端创建的对称密钥的 SealedObject 并将其发送到服务器。
//create cipher using server's public key
Cipher cipher = null;
try {
cipher = Cipher.getInstance(serverKey.getAlgorithm(), "SUN");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
}
try {
cipher.init(Cipher.ENCRYPT_MODE, serverKey);
} catch (InvalidKeyException e) {
e.printStackTrace();
}
但是当我运行程序时,初始化密码时出现异常:
java.security.NoSuchAlgorithmException: No such algorithm: DSA
at javax.crypto.Cipher.getInstance(Cipher.java:646)
at javax.crypto.Cipher.getInstance(Cipher.java:568)
at Client.main(Client.java:91)
我不明白为什么会出现这个 NoSuchAlgorithm 异常。如果我用 RSA 而不是 DSA 制作公钥,我不会得到这个,但 RSA 给了我:
javax.crypto.IllegalBlockSizeException:
Data must not be longer than 117 bytes
那么我应该使用什么来安全地发送包含我的对称密钥的密封对象?
【问题讨论】:
-
你不能使用标准的
SSLServerSocket来代替吗? TLS 大致为您做到了这一点 -
我不能。这是我需要使用对称密钥实现的练习,但首先我必须与服务器安全地共享密钥。
-
没有这样的算法:这里解释了 DSA:crypto.stackexchange.com/questions/2585/…,块大小限制错误的原因是 RSA 也不是常规块密码:stackoverflow.com/questions/685470/… 或 security.stackexchange.com/questions/1878/…,因此可以只能在一定范围内使用,例如在en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange
-
请注意,这一切都是没有意义的,除非客户端有某种方法可以验证服务器的公钥是否确实属于服务器。
标签: java rmi public-key-encryption encryption-symmetric