添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

i am generating a curve25519 ECDH keypair in java like this

public static final String ALGORITHM = "ECDH";
public static final String CURVE = "curve25519";
public static byte[] getEncodedPublicKey(PublicKey key) throws Exception {
        ECPublicKey ecKey = (ECPublicKey) key;
        return ecKey.getQ().getEncoded(true);
Security.addProvider(new BouncyCastleProvider());
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM, PROVIDER);
X9ECParameters ecParameters = CustomNamedCurves.getByName(CURVE);
ECParameterSpec ecSpec = new ECParameterSpec(ecParameters.getCurve(), ecParameters.getG(), ecParameters.getN(), ecParameters.getH(), ecParameters.getSeed());
KeyPair recieverKeypair = keyPairGenerator.initialize(ecSpec, new SecureRandom());
system.out.println(new String(org.bouncycastle.util.encoders.Base64.encode((getEncodedPublicKey(receiverKeyPair.getPublic()))))

and i am using public key that is printed in above in my nodejs project like this

crypto.createPublicKey({
      key: receiverPublicKey, //string
      format:'der',
      type: 'spki',

which throws this error:

Error: error:0D07209B:asn1 encoding routines:ASN1_get_object:too long
    at Object.createPublicKey (node:internal/crypto/keys:595:12)
    at generateSharedKey (/home/wsl/projects/node-ndhm-crypto/src/EncryptData.ts:133:23)
    at Object.exports.encrypt (/home/wsl/projects/node-ndhm-crypto/src/EncryptData.ts:61:21)

any help would be appreciated. thanks.

You should edit your question and include a sample output of the Java part. I would also recommend to post the full key-loading JS code. – Robert Jan 14, 2022 at 12:28

The import fails because both codes use different key formats: Currently, the public key in the Java code is exported in compressed format using ecKey.getQ().getEncoded(true), while the NodeJS code expects the public key in X.509/SPKI format (DER encoded).

If in the Java code ecKey.getEncoded() is used instead, the public key is exported in X.509/SPKI format (DER encoded) and is compatible with the NodeJS side.

Note that in the NodeJS code, a possible Base64 encoding on the Java side must be reversed:
var receiverPublicKey = Buffer.from('<Base64 encoded X.509/SPKI key>', 'base64');

Changing the Java code is probably unavoidable, since importing compressed, uncompressed or raw keys is not supported by crypto.createPublicKey() according to the documentation. The ECDH class, which does handle uncompressed keys, is also not an option since curve 25519 is not supported.

Hey thanks for the answer, but the answer that u wrote first worked for me, i.e, without using getQ so that the message is sent in uncompressed form. do u know a method to tackle it in within nodejs without actually changing it in java? – emkay Jan 14, 2022 at 8:35 AfaIk, unfortunately no, see also the last part of my answer. Btw, I rolled back the answer to the original one. – Topaco Jan 14, 2022 at 16:25

First, to be clear, using curve25519 in Weierstrass form is not standard (at least not yet; draft NIST SP800-186 if and when adopted will allow it with the name W-25519, though it's not clear anybody wants to or will use it for anything) and is definitely not approved by Bernstein; specifically this is NOT compatible with the standard X25519 or XDH25519 algorithm adopted by many protocols and systems, which uses Montgomery-form equation and computations and X-only representation of points. That's probably why Bouncy has it under 'Custom'.

OpenSSL, which underlies nodejs crypto, follows standards (well, this time) and does not support this curve by name in X9/Weierstrass form, but it does support arbitrary 'explicit' Weierstrass curves and (fortunately?) your Java code, by using the X9ECParamters and ECParameterSpec classes, uses the (now generally disfavored) explicit format. The encoding of the SPKI format for X9-type ECDH (and ECDSA) depends on values and their lengths for the curve parameters (fixed for a curve) and the point representation (whose value varies, but has one of two fixed lengths for a curve) -- thus the SPKI format for a curve and point representation consists of a fixed prefix followed by the point representation, and for explicit curve25519(W) compressed that prefix is

"\x30\x82\x01\x11\x30\x81\xea\x06\x07\x2a\x86\x48\xce\x3d\x02\x01"+
"\x30\x81\xde\x02\x01\x01\x30\x2b\x06\x07\x2a\x86\x48\xce\x3d\x01"+
"\x01\x02\x20\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"+
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"+
"\xff\xff\xed\x30\x44\x04\x20\x2a\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"+
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"+
"\xaa\xaa\x98\x49\x14\xa1\x44\x04\x20\x7b\x42\x5e\xd0\x97\xb4\x25"+
"\xed\x09\x7b\x42\x5e\xd0\x97\xb4\x25\xed\x09\x7b\x42\x5e\xd0\x97"+
"\xb4\x26\x0b\x5e\x9c\x77\x10\xc8\x64\x04\x41\x04\x2a\xaa\xaa\xaa"+
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"+
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xad\x24\x5a\x20\xae\x19\xa1"+
"\xb8\xa0\x86\xb4\xe0\x1e\xdd\x2c\x77\x48\xd1\x4c\x92\x3d\x4d\x7e"+
"\x6d\x7c\x61\xb2\x29\xe9\xc5\xa2\x7e\xce\xd3\xd9\x02\x20\x10\x00"+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xde"+
"\xf9\xde\xa2\xf7\x9c\xd6\x58\x12\x63\x1a\x5c\xf5\xd3\xed\x02\x01"+
"\x08\x03\x22\x00"

which you can simply concatenate to what you have (after un-base64-ing as Topaco noted; as a check it must be exactly 33 bytes with the first byte 0x02 or 0x03).

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.