Web Crypto Signature Provider and conversion methods#937
Conversation
Must use already constructed CryptoKey private keys
bogniq
left a comment
There was a problem hiding this comment.
LGTM. Just one comment for clarification.
| const derHex = Buffer.from(extractedDecoded, 'binary').toString('hex'); | ||
| const publicKeyHex = derHex.replace('3059301306072a8648ce3d020106082a8648ce3d030107034200', ''); | ||
| const publicKeyEc = ec.keyFromPublic(publicKeyHex, 'hex'); | ||
| return PublicKey.fromElliptic(publicKeyEc, KeyType.r1, ec); |
There was a problem hiding this comment.
Just to confirm, could ec be initially passed non-empty and of type secp256k1, or only p256 is supported here?
There was a problem hiding this comment.
Only p256 is supported for the Web Crypto API but it is possible that someone could put a k1 ec object and the code would break. I think a check is likely needed, I'll add it.
There was a problem hiding this comment.
Actually, turns out the elliptic library does not easily label the curve utilized in the object. It would not be as simple as checking ec.curve.label = 'p256';. I will remove the ability of providing an ec object to the functions.
| let recoveredKey: any; | ||
| for (let i = 0; i < 4; i++) { | ||
| try { | ||
| const keyPair = ec.recoverPubKey(digest, signature, i); |
There was a problem hiding this comment.
Name keyPair is a bit confusing as private key is not here.
There was a problem hiding this comment.
Actually the recoverPubKey function will return an ec keyPair object, although the private will be empty and the public will be non-empty.
CI/CD changes for PRs #937/#963/#964 - merging per a request from Brad this is a bug with github actions, version 12.14.1 has been replaced by the v15.14.0 ones, can you override and merge it? It also might be because I have to copy the workflow files to master but I won't be certain until this one is merged Will be verified and can be reverted if something else breaks.
nksanthosh
left a comment
There was a problem hiding this comment.
Per BLU-20451 this is now ready for merge. Please address the docs change requested.
docs/basic-usage/index.md
Outdated
| In production code, it is recommended that you use a secure vault outside of the context of the webpage (which will also implement the `eosjs-api-interfaces.SignatureProvider` interface) to ensure security when signing transactions. | ||
|
|
||
| ## WebCryptoSignatureProvider | ||
| Additionally, `WebCryptoSignatureProvider` is available in `eosjs` as a more secure built-in `SignatureProvider` than `JsSignatureProvider`. Utilizing the [SubtleCrypto interface of the Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto), the `WebCryptoSignatureProvider` provides functionality for signing transactions utilizing CryptoKeys created by Web Crypto. There are several methods available as well to convert extractable CryptoKeys into PrivateKey/PublicKey `eosjs` formats, which can then be converted into string or `elliptic` keypairs. The method `generateWebCryptoKeyPair` is also available to create a CryptoKeyPair where the private CryptoKey is non-extractable and the public CryptoKey is extractable. This is intentional as an extractable private key is more insecure than a non-extractable private key. There are several more security concerns that you will need to address when it comes to utilizing the Web Crypto API, such as secure key management, so only utilize the `WebCryptoSignatureProvider` if you are aware of these security requirements and the risks involved in insecure environments. No newline at end of file |
There was a problem hiding this comment.
Please remove this section and provide a stub in its place and once the documentation is created and signed off by Product and Developer Relations - they can PR those changes in via a separate PR. Other than that this PR is now ready to merge per BLU-20451
|
@bradlhart What is the status of this PR? |
Change Description
The Web Crypto API, or otherwise referred as SubtleCrypto, has the ability to construct or import both public and private keys as well as sign data using the private key CryptoKey. The format of the CryptoKey and Signature are different than eosjs built-in format and elliptic format. This code adds functionality to convert from eosjs built-in format to CryptoKeys as well as CryptoKeys and Signature to eosjs format.
Lastly, this code also includes a Web Crypto Signature Provider that can be used to store keys and sign transactions before sending to nodeos.
API Changes
Added:
PrivateKey.toWebCrypto(): converts PrivateKey to private CryptoKeyPrivateKey.fromWebCrypto(): converts private CryptoKey to PrivateKeyPrivateKey.webCryptoSign(): signs data in Web Crypto method (sha256 hashing is done within Web Crypto method)PublicKey.toWebCrypto(): converts PublicKey to public CryptoKeyPublicKey.fromWebCrypto(): converts public CryptoKey to PublicKeySignature.fromWebCrypto(): converts Web Crypto-created signature to SignatureNew:
WebCryptoSignatureProvidersignature provideraddCryptoKeyPair: convenient method to add a CryptoKeyPair to the signature provider, rather than populatingkeysandavailableKeysmanuallysign: creates a buffer to sign utilizing Web Crypto's sign method and converts the outputted signature to a Signature classDocumentation Additions
Added a concise section about the new WebCryptoSignatureProvider