Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用公钥/私钥签名进行身份验证:什么';这是个好消息(摘要)?_Java_Security_Authentication_Digital Signature_Public Key Encryption - Fatal编程技术网

Java 使用公钥/私钥签名进行身份验证:什么';这是个好消息(摘要)?

Java 使用公钥/私钥签名进行身份验证:什么';这是个好消息(摘要)?,java,security,authentication,digital-signature,public-key-encryption,Java,Security,Authentication,Digital Signature,Public Key Encryption,我正在使用客户机/服务器基础架构构建一个应用程序,并希望使用公钥/私钥方法实现一个身份验证机制 假设客户机拥有私钥,而服务器只有公钥。在身份验证过程中,客户端使用私钥对消息进行签名,并将其发送到服务器,在服务器上使用公钥对其进行验证。如果验证成功,则对客户端进行身份验证 下面是我熟悉的一些JUnit测试代码: @Test public void testSignature() throws Exception { final String message = "Hello world i

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

假设客户机拥有私钥,而服务器只有公钥。在身份验证过程中,客户端使用私钥对消息进行签名,并将其发送到服务器,在服务器上使用公钥对其进行验证。如果验证成功,则对客户端进行身份验证

下面是我熟悉的一些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));
}
当然,为了使其工作,服务器和客户端都必须拥有普通消息(摘要)


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

静态字符串可能不好,因为它容易受到重复攻击(签名字符串每次都相同)

尽管如此,您似乎正在重新发明以前所做的事情。使用证书是值得信任的方式。有关详细信息,请参见此示例:


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

您不想使用客户端证书进行标准SSL/TLS握手有什么原因吗?没有原因。我现在正在评估不同的选择。但是,我也希望使用私钥进行加密。具有相同密钥(相同用户)的客户端应该能够发送/接收加密消息,而服务器无法对其进行解码。如果您不介意打开厨房水槽,您可以尝试使用支持中介(例如您的服务器)并允许消息级身份验证和加密的SOAP。我仍在理解签名是如何工作的。有人能解释一下我怎么看不到任何“证书”吗?据我所知,您需要使用证书和私钥(验证发件人所需的证书)对邮件进行签名。“签名”(字节[])就是这里的证书吗?解决重播问题的一个简单变体就是使用一个大数字,每次进行身份验证时都会增加这个数字。然后客户机/服务器只需要使用最后一个。我通常不想重新发明轮子:)客户机/服务器通过HTTP REST API进行通信。服务器将是一个WAR文件,它将被部署到应用服务器。因此,我不能假设应用服务器启用了HTTPS,因为它超出了我的控制范围。你推荐什么?这是真的。这将是一个非常简单的想法,而不是大量的if字符串。一个共享的数字如何与多个客户端协同工作?但我想我有一个想法:每个客户端在创建过程中都会得到服务器分配的唯一ID。因此,客户端和服务器都知道UUID。我不能将此UUID用作摘要身份验证的消息吗?每个客户端可能都有一个ID,例如“Client1”,还有一个数字,例如1。服务器需要存储Client1->1、Client2->1等。当客户端1与服务器进行身份验证时,它会说,我是Client1,现在正在进行身份验证,它使用数字1。然后,服务器收到消息,知道要发送1。一旦身份验证成功,它会将客户端1的编号增加,因此现在客户端1->2,客户端2->1。客户端1也需要增加其内部号码,以便下次发送2。等等这是最基本的原则,你开始时可能是随机的,但双方都必须知道