【问题标题】:Node.js crypto key creation using Java使用 Java 创建 Node.js 加密密钥
【发布时间】:2020-03-06 11:38:27
【问题描述】:

我在 node.js 中有这段代码,它使用 Crypto 创建密钥。 我可以使用 Java 创建相同的密钥吗?

diffieHellmanConfig': {
      'group': 'modp14',
      'encoding': 'base64'
    }


 const clientDHInstance = crypto.getDiffieHellman(config.userCardCrypto.diffieHellmanConfig.group);
 clientDHInstance.generateKeys();

 const clientPublicKey = clientDHInstance.getPublicKey(config.userCardCrypto.diffieHellmanConfig.encoding);

我尝试使用

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DH");
keyGen.initialize(2048);
KeyPair keypair = keyGen.genKeyPair();
PrivateKey privateKey = keypair.getPrivate();
PublicKey publicKey = keypair.getPublic();
byte[] encoded = publicKey.getEncoded();
String s = Base64.getEncoder().encodeToString(encoded);
System.out.println(s);

但是钥匙错了

节点键是 t2EBMu8wCShfu8Dm45i9nNQ + TXyG5Oz1 / izjTwRD0dchUK2400R9cP + NjLlOqjLstXnTbG5 / aa0WaCoP187J90piiebGOjZUlF / BU / xkkrYncQHAJ403J8 + R2V5eHYCSQXbS6CSO7x + eEhNz8QTMgwkOR9w1R3gvbibaqL7qyQARPFak6 + VIKFLUakSzMvdAIjLNPu2dva1QdJixid + EYiZE / DxA7lqpje74I7wynZj7kmUZXtiIWu46suf5CaVONtjEVZilvErJNpVlPX5TXoMVNrWkl9g5Aa6moXg4K0M6Gc4taumnDr9gh4PEuw + / QVauEld27 / 5TQlfAlalvzg == P>

Java 键是 MIICKTCCARsGCSqGSIb3DQEDATCCAQwCggEBAP ////////// YQ / aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu + pjsTmyJRSgh5jjQE3e + VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL / 1y29Aa37e44a /塔伊兹+ lrp8kEXxLH + ZJKGZR7ORbPcIAfLihY78FmNpINhxV05ppFj + O / STPX4NlXSPco62WHGLzViCFUrue1SkHcJaWbWcMNU5KvJgE8XRsCMoYIXwykF5GLjbOO + OedywYDoYDmyeDouwHoo + 1xV3wb0xSyd4ry / aVWBcYOZVJfOqVauUV0iYYmPoFEBVyjlqKrKpo ////////// 8CAQICAgQAA4IBBgACggEBAI + NYSvMh0bfh1ptt62vHEHENz6ZAYvnnrwmRhQRdYMBZiqu60AvJ4F6qL99EfesxvH3n8YaC + cG7bKAqkw74rRHJXkMF5xOy / kpTVvmQGAPjvTi5o4BJtHLOBgiwFKy7CYFKFksCJzkqNdAuPri / mfMm6GNG5MBYtQIurWkgOnnrVl3Nra2CSVUixQ5zCANOSnnNYNFPanr01bI6KZXsiRZRqfA4oYxBPySy4Sp1dx2IvSQe8EjNWTicTQQj / HP7hl1yf3uiYlM4h3dMbmfqv6Y10hW8kvoD88 / mh09pdz + HxxDz + mVSMe + 3 + N7VIYUEGRHhrAvjbXmwh5zyCMIJiI =

【问题讨论】:

  • 钥匙有什么问题?当您说“相同”键时,您的意思是相同的大小,对吗?或者您实际上想要生成相同的密钥实例?即字面上相同的密钥字节...当您调用 genKeyPair() 或 generateKeys() 时,您当然会根据定义获得不同的密钥材料。
  • @Woodstock Java 密钥比节点大,当我尝试将它发送到服务器时,我得到了响应 {"code":500,"message":"Supplied key is too large"}跨度>
  • 你能提供两个示例键,一个来自节点,一个来自 Java,以便我看看格式吗?
  • @Woodstock 更新问题
  • 好吧,我想通了,会写答案

标签: java node.js cryptography diffie-hellman


【解决方案1】:

在您的示例密钥中,节点创建的 DH 密钥的大小是预期的 2048 位,但是,Java DH 密钥正在推入 ~4k 位。

所以我认为您在 Java 上初始化 DH 密钥的方式有问题。

查看您的代码,我认为提供整数文字来指定 DH 循环组的大小是不合适的。

尝试像这样实例化您的 Java DH 密钥:

  final DHParameterSpec keySpec=new DHParameterSpec(DH_MODULUS,DH_BASE);
  final KeyPair keyPair;
  try {
    KeyPairGenerator keyGen=KeyPairGenerator.getInstance("DH");
    keyGen.initialize(keySpec);
    keyPair=keyGen.generateKeyPair();
    PrivateKey privateKey = keyPair.getPrivate();
    PublicKey publicKey = keyPair.getPublic();
    byte[] encoded = publicKey.getEncoded();
    String s = Base64.getEncoder().encodeToString(encoded);
    System.out.println(s);
  }

您需要在 Java 中创建一个 DHParameterSpec 对象,提供模数和基数,类似于节点中提供的值。

例子:

public DHParameterSpec modp14() {
  final BigInteger p =
      new BigInteger(
          "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
              + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
              + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
              + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
              + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
              + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
              + "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
              + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
              + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
              + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
              + "15728E5A8AACAA68FFFFFFFFFFFFFFFF",
          16);
  final BigInteger g = new BigInteger("2");
  return new DHParameterSpec(p, g);
}

请参阅here 了解有关素数组的规范。

【讨论】:

  • 谢谢,但是如何找到节点中提供的值
  • @ MichaelSych由节点使用的素数实际上是总是ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff和所述碱是2。跨度>
  • 我更新了我的代码以反映您的初衷@MichaelSych,如果这对您有用,请将问题标记为已回答。
  • Java 密钥 2048 位(并且是公开的),但采用 X.509 SubjectPublicKeyInfo 格式,如 javadoc 中为 Key 指定的那样,其中包含参数(p 和 g)以及实际密钥(y)加上一些开销,使表示总共 557 个字节。至少现在 Java 确实使用了 size=2048 的第 14 组参数,但这并不能保证,并且自己指定它们确实更好。 @MichaelSych:“始终相同”的初始部分是包含 OID 和参数的外部 TLV 和 X.509 AlgorithmId,它们应该是相同的。
  • @MichaelSych+ 如果您只想要 y 值,请使用 ((DHPublicKey)publicKey).getY().toByteArray() 并在必要时将结果修剪(或在极少数情况下填充)到 256 字节。并根据需要转换为 base64。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-05
  • 2015-08-13
  • 1970-01-01
  • 2013-05-15
  • 1970-01-01
  • 2015-05-02
  • 1970-01-01
相关资源
最近更新 更多