Skip to content

crypto: add support for SM2

These commits add support for SM2 from the SM9 standard. It requires a fair amount of hacks within our codebase, so if anyone has any other integration ideas, I'd be happy to hear them.

Asymmetric Key Type 'sm2'

A new asymmetric key type is added: 'sm2'.

Unlike previous asymmetric key types, it does not have a unique OID, and does, in fact, share an OID with 'ec', meaning that there is no longer a 1:1 correlation between OIDs and asymmetric key types.

Key Pair Generation

SM2 key pairs can be generated using crypto.generateKeyPair('sm2').

No options are accepted.

Digital Signatures

SM2 signatures require an additional "identifier" that must be specified by the signing and the verifying party. To accomodate this, an sm2Identifier option was added to crypto.sign and crypto.verify.

There is no documented way of producing SM2 signatures with the OpenSSL APIs that we are using in the Sign and Verify classes. Therefore, these classes currently do not support SM2 signatures.

Key Agreement

Currently not implemented due to lack of support within OpenSSL. Might also be insecure in its original form, see Xu et al. doi:10.1007/978-3-642-25513-7_12:

In this paper, we have shown that the SM2 key exchange protocol is potentially vulnerable to an unknown key-share attack. The weakness is due to the fact that the identifiers of the communicants are not appropriately integrated into the exchanged cryptographic messages. However, the attack presented here should not discourage use of the SM2 protocol, as long as appropriate countermeasures are taken. We also have suggested a simple modification to resist our described attacks while the merits of the original protocol are left unchanged.

Should be added to crypto.diffieHellman() if it makes sense in the future.

Key Import

Because the PKCS#8 and SPKI encodings of SM2 keys are indistinguishable from EC keys on the SM2 curve, the createPublicKey and createPrivateKey functions now accept an additional asymmetricKeyType option. If specified, Node.js will attempt to create a KeyObject of the given type. As a side effect, this allows users to enforce a specific asymmetric key type when importing key material, e.g., 'rsa'. For SM2, this means that the key will first be parsed as EC, and its type will then be changed to SM2 if the user specified asymmetricKeyType: 'sm2'.

The default behavior matches OpenSSL: When loading a key with OID 1.2.840.10045.2.1 on the SM2 curve without specifying asymmetricKeyType: 'sm2', it will create an EC key, not an SM2 key.

Note on SM3

While OpenSSL 1.1.1 supports SM3 as a hash function and as the digest for SM2 signatures, it does not allow SM3 as the digest for other signatures. Future releases might change that.

Merge request reports

Loading