我正在构建一个具有客户端/服务器基础架构的应用程序,并希望使用公钥/私钥方法实现身份验证机制。
假设客户端拥有私钥,而服务器只有公钥。在身份验证期间,客户端使用私钥对消息进行签名,然后将其发送到使用公钥对其进行验证的服务器。如果验证成功,则客户端通过身份验证。
这是一些 JUnit 测试代码,我在其中熟悉了这些概念:
@Test
public void testSignature() throws Exception {
final String message = "Hello world is a stupid message to be signed";
final KeyPair keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
final Signature privSig = Signature.getInstance("SHA1withRSA");
privSig.initSign(keyPair.getPrivate());
privSig.update(message.getBytes());
byte[] signature = privSig.sign();
final Signature pubSig = Signature.getInstance("SHA1withRSA");
pubSig.initVerify(keyPair.getPublic());
pubSig.update(message.getBytes());
assertTrue(pubSig.verify(signature));
}
当然,为了使其工作,服务器和客户端都必须拥有纯消息(摘要)。
现在我的问题是:用于签名的好消息(摘要)是什么?例如,这可以是一个静态的、硬编码的字符串(用于所有客户端)还是会给这个概念带来某种安全问题?如果静态字符串不好,在身份验证之前协商一些随机字符串是个好主意吗?例如,这个随机字符串可以用作“会话”密钥,并在一段时间后失效。