Java 从赫尔曼到埃斯

Java 从赫尔曼到埃斯,java,encryption,cryptography,diffie-hellman,Java,Encryption,Cryptography,Diffie Hellman,我正在尝试创建一个应用程序,它可以使用加密数据将数据从客户端发送到服务器。我已经在Java中建立了一个基本的Diffie-Hellman密钥交换,我只是想知道如何将其转换为AES-128密钥。以下是我的密钥交换生成的数字: p:4573933405200148638398211571439556564285236154694312030506329340808505575737540408930275236822193734849358157382669648334705864404021436

我正在尝试创建一个应用程序,它可以使用加密数据将数据从客户端发送到服务器。我已经在Java中建立了一个基本的Diffie-Hellman密钥交换,我只是想知道如何将其转换为AES-128密钥。以下是我的密钥交换生成的数字:

p:4573933405200148638398211571439556564285236154694312030506329340808505575737540408930275236822193734849358157382669648334705864404021436560169515686563654746844010747338983113663865631185640042274978107007323073169714532843785763128771045137747777868127772692600346003
g:405
生产密钥:3624844161031604373940723150439573936645456312032028064365240345591632292456385336418395841257359594423512887912569551847751145040868625559588574146884458270851590182479620096397780000068069775531222140355988113960886218591348554031415699336803706159212234266666636792781180354
p和生成的密钥都有299个字符长。我自己也尝试过解决这个问题,并阅读了有关使用SHA-256对生成的密钥进行散列的内容,结果如下:

SHA-256:4631d862806f2c22ae28959a8ffb441789ab306468d6bf04d87435dd81890519
然而,我看不出如何将这些转换成16字节(128位)的密钥。例如{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}。我要取结果的前16个数字吗?

任何帮助或信息都将是令人惊讶的,我将非常感谢。如果需要更多的信息,请直接问我

  • (可选)对密钥交换的
    a
    b
    秘密参数使用128位值
  • 将结果值
    s
    转换为字节数组并获取任意16个元素。您不需要将
    s
    转储到十六进制字符串中,也不需要对该字符串进行散列
  • 您需要的是a,它将接收任何包含足够随机性(如共享秘密)的位字符串作为输入,并对其进行“置乱”,以生成一个或多个固定长度的均匀随机位字符串,例如,适合用作密钥

    您可以使用许多标准化的KDF,但是如果您想要一个具体的推荐,我非常喜欢()。 它是一种“提取和扩展”类型的KDF,这意味着它首先将输入字符串处理为内部主密钥字符串(在规范中称为“PRK”),然后可以使用该字符串派生任意数量的密钥材料

    HKDF是一种通用的高级构造,可以使用任何安全的方法进行实例化,例如,即使您的加密库不提供内置的HKDF实现,也不难自己编写一个。RFC中的规范写得很好,可读性也很好,我非常建议花几分钟来阅读它

    与大多数KDF一样,HKDF的扩展步骤采用可选的“info”字符串,用于调整密钥派生过程,以便可以重用相同的输入字符串(或PRK)来派生多个(有效地)独立密钥,只要每个密钥使用不同的“info”字符串。(用于从输入字符串导出PRK的提取阶段也采用具有类似效果的“salt”参数。)


    有人认为HKDF没有这样做,如果输入是用户选择的密码,这是有用的(有些人会说是必要的)。如果需要,您可以使用例如或。(也可以将HKDF的提取阶段替换为PBKDF2,并按原样使用扩展阶段;事实上,我建议使用PBKDF2生成多个哈希块的关键材料。)幸运的是,使用Diffie–Hellman,共享秘密具有足够的熵,因此密钥拉伸是不必要的。

    您考虑过TLS吗?我没有研究过它,但是现在我会的,因为您也引起了我的注意。仅仅执行DH本身是不安全的,一如往常,请听代码:)如果我选择第二个选项,那么总是使用前16个字节就足够了,还是这会降低安全性?或者更确切地说,我应该随机选取一组字节,然后告诉服务器/客户机从哪个位置获取它们的字节?我也在想同样的问题,但第一个(对于big-endian系统来说是最左边的)是16个字节。要使用“正确”的加密方法,您应该使用一个或多个对KBKDF(基于密钥的密钥派生方法)的调用,例如HKDF。仅使用SHA-256并获取结果的前128字节可以被视为糟糕的mans KDF。感谢您提供的信息,但是我认为现在我只需要从结果中随机获取字节,然后告诉服务器/客户端我从哪个位置查看。不过,我将在将来研究您所说的。@user2124641:,但我仍然建议使用HKDF。它其实非常简单,只要有SHA-256这样的散列函数就行。