java - 使用公钥/私钥签名进行身份验证 : What's a good message (digest)?

标签 java security authentication digital-signature public-key-encryption

我正在构建一个具有客户端/服务器基础结构的应用程序,并希望使用公钥/私钥方法实现身份验证机制。

假设客户端拥有私钥,而服务器只有公钥。在身份验证期间,客户端使用私钥签署消息,将其发送到使用公钥验证的服务器。如果验证成功,则客户端通过身份验证。

这是一些 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));
}

当然,为了使其正常工作,服务器和客户端都必须拥有明文消息(摘要)。

现在我的问题是:什么是用于签名的好消息(摘要)?例如,这可以是一个静态的、硬编码的字符串(用于所有 客户端),或者这是否会给这个概念带来某种安全问题?如果静态字符串不好,在身份验证之前协商一些随机字符串是个好主意吗?例如,这个随机字符串可以用作“ session ” key ,并在一段时间后失效。

最佳答案

静态字符串会很糟糕,因为它容易受到重复攻击(签名字符串每次都相同)。

尽管如此,您似乎正在重新发明以前做过的事情。使用证书是值得信赖的方式。有关更多信息,请参阅此示例:Java HTTPS client certificate authentication

如果您想自己实现它,您可能需要阅读 SSL 的工作原理并模仿它。任何其他解决方案都可能存在一些缺陷,除非它是非常定制的(例如,您的客户端将保留 1000 个它从未重复使用的共享静态字符串的列表,并且服务器具有相同的列表并跟踪已更改的内容使用。或者,跟踪一个递增的共享数字,如以下评论中所建议的。)

关于java - 使用公钥/私钥签名进行身份验证 : What's a good message (digest)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10288521/

相关文章:

php - 强制密码要求

c# - 如何为 MVC .Net Core 应用创建单个管理员用户

authentication - ASP.Net Core 从 VS2015 迁移到 VS2017 时,无法加载文件或程序集“System.Diagnostics.DiagnosticSource”

java - 如何解析只有日期名称的日期?

java - 将 BufferedImage 添加到 PDFBox 文档

java - 如何以及何时计算静态最终字段值?

java - 在 onCreate 调用期间重新定义 Java 类的变量?

安全错误: DOM Exception 18 on using getImageData in a Chrome Extension

c# - 我在这里正确使用锁吗?我应该尝试用它包装更少的代码吗?

python - API 错误解释带有特殊字符的密码