Comments (7)
I don't find it hard to believe that there are other libraries out there that'll accept JWKs that are somewhat malformed.
I'm guessing that you could simply remove the padding and possibly prepend the y
member with zeros. But the fact that the y
member has the wrong length, should probably be a warning flag -- maybe there is something wrong with the key.
In any case, unless we can somehow reasonably say that the input is a valid JWK and would be accepted by most other webcrypto implementations, then I suggest we close this issue.
from webcrypto.dart.
cc @jonasfj
from webcrypto.dart.
What happens if you do this in a various browsers?
window.crypto.subtle.importKey(
'jwk', {
"kty": "EC",
"crv": "P-256",
"x": "h0rbX_vxGVgx-u-ITxnydyy7W9VNGFITcqltL7hDa5A=",
"y": "iQdcRQ8aghMIKnnE1RZEzrfag4c2PHBq8kVea6tK6w==",
"d": "A-zAYOf8KYYxZvP6akkL6SNjBPygstC7VALP2cuh0QA="
}, {
"name": "ECDH",
"namedCurve": "P-256"
}, true, ['deriveKey']
).then(
k => console.log(k)
).catch(
err => console.log(err)
);
Fails for me on both Chrome and Firefox.
This indicates to me that the JWK might be malformed or incorrectly formatted.
from webcrypto.dart.
BASE64URL(OCTETS) denotes the base64url encoding of OCTETS, per
Section 2 of [JWS].
From: https://datatracker.ietf.org/doc/html/rfc7517#section-1.1
Base64url Encoding
Base64 encoding using the URL- and filename-safe character set
defined in Section 5 of RFC 4648 [RFC4648], with all trailing '='
characters omitted (as permitted by Section 3.2) and without the
inclusion of any line breaks, whitespace, or other additional
characters. Note that the base64url encoding of the empty octet
sequence is the empty string. (See Appendix C for notes on
implementing base64url encoding without padding.)
From: https://www.rfc-editor.org/rfc/rfc7515.html#section-2
from webcrypto.dart.
Is there any reason to think this is a valid JWK? What other libraries that understand JWKs will accept this JWK?
from webcrypto.dart.
What happens if you do this in a various browsers?
window.crypto.subtle.importKey( 'jwk', { "kty": "EC", "crv": "P-256", "x": "h0rbX_vxGVgx-u-ITxnydyy7W9VNGFITcqltL7hDa5A=", "y": "iQdcRQ8aghMIKnnE1RZEzrfag4c2PHBq8kVea6tK6w==", "d": "A-zAYOf8KYYxZvP6akkL6SNjBPygstC7VALP2cuh0QA=" }, { "name": "ECDH", "namedCurve": "P-256" }, true, ['deriveKey'] ).then( k => console.log(k) ).catch( err => console.log(err) );Fails for me on both Chrome and Firefox.
This indicates to me that the JWK might be malformed or incorrectly formatted.
I also fail on Chrome with error DOMException: The JWK member "x" could not be base64url decoded or contained padding
. If remove =
in x, y, d
it's will show DOMException: The JWK's "y" member defines an octet string of length 31 bytes but should be 32
.
But when i run it on node js with library packages below it works fine.
Here is my example project: https://github.com/leanhdaoit/chat-e2e-example
Logs of example:
===========Import key by old @peculiar/webcrypto=============
jwk: {"kty":"EC","crv":"P-256","x":"h0rbX_vxGVgx-u-ITxnydyy7W9VNGFITcqltL7hDa5A","y":"iQdcRQ8aghMIKnnE1RZEzrfag4c2PHBq8kVea6tK6w","d":"A-zAYOf8KYYxZvP6akkL6SNjBPygstC7VALP2cuh0QA"}
privateKey:[object CryptoKey]
===========Import key by old webcrypto=============
jwk: {"kty":"EC","crv":"P-256","x":"h0rbX_vxGVgx-u-ITxnydyy7W9VNGFITcqltL7hDa5A","y":"iQdcRQ8aghMIKnnE1RZEzrfag4c2PHBq8kVea6tK6w","d":"A-zAYOf8KYYxZvP6akkL6SNjBPygstC7VALP2cuh0QA"}
privateKey:[object Object]
maybe the old libraries don't check the format of the x and y points, but it can still do deriveKey and encrypt/decrypt (AES-GCM)
from webcrypto.dart.
I can confirm that after padLeft zero with length 32 of y
it works fine.
Code Example:
import 'package:webcrypto/webcrypto.dart';
import 'package:elliptic/elliptic.dart' as elliptic;
Map<String, String> convertPrivateKeyHexToJWK(String privateKeyHex) {
final privateKeyEC = convertPrivateKeyHexToEC(privateKeyHex);
final encodedX = encodeBigInt(privateKeyEC.publicKey.X);
final encodedXPadLeft = padLeft(encodedX, 32, 0);
final encodedY = encodeBigInt(privateKeyEC.publicKey.Y);
final encodedYPadLeft = padLeft(encodedY, 32, 0);
final encodedD = encodeBigInt(privateKeyEC.D);
final encodedDPadLeft = padLeft(encodedD, 32, 0);
final privateKeyJWK = {
'kty': 'EC',
'crv': 'P-256',
'x': base64UrlEncode(encodedXPadLeft),
'y': base64UrlEncode(encodedYPadLeft),
'd': base64UrlEncode(encodedDPadLeft)
};
return privateKeyJWK;
}
elliptic.PrivateKey convertPrivateKeyHexToEC(String privateKeyHex) =>
elliptic.PrivateKey.fromHex(elliptic.getP256(), privateKeyHex);
Uint8List encodeBigInt(BigInt number) {
final _byteMask = BigInt.from(0xff);
final size = (number.bitLength + 7) >> 3;
final result = new Uint8List(size);
for (int i = 0; i < size; i++) {
result[size - i - 1] = (number & _byteMask).toInt();
number = number >> 8;
}
return result;
}
Uint8List padLeft(
Uint8List input, int desiredLength, int paddingValue) {
if (input.length >= desiredLength) {
return input;
} else {
var padding = Uint8List(desiredLength - input.length);
padding.fillRange(0, padding.length, paddingValue);
return Uint8List.fromList([...padding, ...input]);
}
}
from webcrypto.dart.
Related Issues (20)
- update kotlin version
- Lacks support for pure-Dart use HOT 1
- update ffigen HOT 4
- Possible to split into packages so that the non-flutter parts can be used in a non-flutter project? HOT 2
- Can't use in a Dart web environment only. HOT 1
- Ques: How to generate public/private Key RSA-OAEP ? HOT 1
- Explore wrap/unwrap/derive-key and capabilities
- Consider adopting test vectors from chromium
- Extend TestRunner with support for exception and error cases
- Refactor test case generation
- Run tests under valgrind HOT 1
- Reject JWK keys that have conflicting "use" and "key_ops"
- Bespoke test cases for import JWK with conflicting "use" and "key_ops"
- Ensure CBS is empty after importing keys
- Consider augmenting _Scope to ensure we clear errors after each operation HOT 1
- Write documentation for all public members
- Ensure correct handling of errors from thread-local storage
- AesGcmSecretKey.importRawKey on Chrome - Expected a value of type 'CryptoKey' (in null), but got one of type 'CryptoKey' HOT 1
- ECDSA Key Generation Fails on Mobile Web Browser HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from webcrypto.dart.