// SEQUENCE // SEQUENCE // OBJECT IDENTIFIER 1.2.840.10045.2.1 // OBJECT IDENTIFIER EC curve OID // BIT STRING public key private static ECJwk ReadECPublicKey(ref AsnReader reader, int[] curveOid) { var publicKey = reader.ReadBitStringBytes(); if (publicKey.IsEmpty) { ThrowHelper.ThrowInvalidOperationException_InvalidPem(); } if (publicKey[0] != 0x04) { ThrowHelper.ThrowInvalidOperationException_InvalidPem(); } if ((publicKey.Length & 0x01) != 1) { ThrowHelper.ThrowInvalidOperationException_InvalidPem(); } int fieldWidth = publicKey.Length / 2; var x = publicKey.Slice(1, fieldWidth).ToArray(); var y = publicKey.Slice(1 + fieldWidth).ToArray(); if (reader.Read()) { ThrowHelper.ThrowInvalidOperationException_InvalidPem(); } if (IsP256(curveOid)) { return(ECJwk.FromByteArray(EllipticalCurve.P256, x: x, y: y)); } else if (IsP384(curveOid)) { return(ECJwk.FromByteArray(EllipticalCurve.P384, x: x, y: y)); } else if (IsP521(curveOid)) { return(ECJwk.FromByteArray(EllipticalCurve.P521, x: x, y: y)); } else { throw new NotSupportedException(); } }
public void Factory() { var x = Base64Url.Decode("MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4"); var y = Base64Url.Decode("4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM"); var d = Base64Url.Decode("TEkodhWr0iujjHVx7BcV0llS4w5ACGgPrcAd6ZcSR01"); // FromBase64Url var key = ECJwk.FromBase64Url(EllipticalCurve.P256, x: "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", y: "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", KeyManagementAlgorithm.EcdhEs, computeThumbprint: true); Assert.True(key.X.SequenceEqual(x)); Assert.True(key.Y.SequenceEqual(y)); Assert.Equal(0, key.D.Length); Assert.NotEqual(0, key.Kid.EncodedUtf8Bytes.Length); key = ECJwk.FromBase64Url(EllipticalCurve.P256, x: "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", y: "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", KeyManagementAlgorithm.EcdhEs, computeThumbprint: false); Assert.True(key.X.SequenceEqual(x)); Assert.True(key.Y.SequenceEqual(y)); Assert.Equal(0, key.D.Length); Assert.Equal(0, key.Kid.EncodedUtf8Bytes.Length); key = ECJwk.FromBase64Url(EllipticalCurve.P256, x: "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", y: "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", d: "TEkodhWr0iujjHVx7BcV0llS4w5ACGgPrcAd6ZcSR01", KeyManagementAlgorithm.EcdhEs, computeThumbprint: true); Assert.True(key.X.SequenceEqual(x)); Assert.True(key.Y.SequenceEqual(y)); Assert.True(key.D.SequenceEqual(d)); Assert.NotEqual(0, key.Kid.EncodedUtf8Bytes.Length); key = ECJwk.FromBase64Url(EllipticalCurve.P256, x: "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", y: "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", d: "TEkodhWr0iujjHVx7BcV0llS4w5ACGgPrcAd6ZcSR01", KeyManagementAlgorithm.EcdhEs, computeThumbprint: false); Assert.True(key.X.SequenceEqual(x)); Assert.True(key.Y.SequenceEqual(y)); Assert.True(key.D.SequenceEqual(d)); Assert.Equal(0, key.Kid.EncodedUtf8Bytes.Length); key = ECJwk.FromBase64Url(EllipticalCurve.P256, x: "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", y: "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", SignatureAlgorithm.ES256, computeThumbprint: true); Assert.True(key.X.SequenceEqual(x)); Assert.True(key.Y.SequenceEqual(y)); Assert.Equal(0, key.D.Length); Assert.NotEqual(0, key.Kid.EncodedUtf8Bytes.Length); key = ECJwk.FromBase64Url(EllipticalCurve.P256, x: "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", y: "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", SignatureAlgorithm.ES256, computeThumbprint: false); Assert.True(key.X.SequenceEqual(x)); Assert.True(key.Y.SequenceEqual(y)); Assert.Equal(0, key.D.Length); Assert.Equal(0, key.Kid.EncodedUtf8Bytes.Length); key = ECJwk.FromBase64Url(EllipticalCurve.P256, x: "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", y: "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", d: "TEkodhWr0iujjHVx7BcV0llS4w5ACGgPrcAd6ZcSR01", SignatureAlgorithm.ES256, computeThumbprint: true); Assert.True(key.X.SequenceEqual(x)); Assert.True(key.Y.SequenceEqual(y)); Assert.True(key.D.SequenceEqual(d)); Assert.NotEqual(0, key.Kid.EncodedUtf8Bytes.Length); key = ECJwk.FromBase64Url(EllipticalCurve.P256, x: "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", y: "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", d: "TEkodhWr0iujjHVx7BcV0llS4w5ACGgPrcAd6ZcSR01", SignatureAlgorithm.ES256, computeThumbprint: false); Assert.True(key.X.SequenceEqual(x)); Assert.True(key.Y.SequenceEqual(y)); Assert.True(key.D.SequenceEqual(d)); Assert.Equal(0, key.Kid.EncodedUtf8Bytes.Length); // FromByteArray key = ECJwk.FromByteArray(EllipticalCurve.P256, x: x, y: y, KeyManagementAlgorithm.EcdhEs, computeThumbprint: true); Assert.True(key.X.SequenceEqual(x)); Assert.True(key.Y.SequenceEqual(y)); Assert.Equal(0, key.D.Length); Assert.NotEqual(0, key.Kid.EncodedUtf8Bytes.Length); key = ECJwk.FromByteArray(EllipticalCurve.P256, x: x, y: y, KeyManagementAlgorithm.EcdhEs, computeThumbprint: false); Assert.True(key.X.SequenceEqual(x)); Assert.True(key.Y.SequenceEqual(y)); Assert.Equal(0, key.D.Length); Assert.Equal(0, key.Kid.EncodedUtf8Bytes.Length); key = ECJwk.FromByteArray(EllipticalCurve.P256, x: x, y: y, d: d, KeyManagementAlgorithm.EcdhEs, computeThumbprint: true); Assert.True(key.X.SequenceEqual(x)); Assert.True(key.Y.SequenceEqual(y)); Assert.True(key.D.SequenceEqual(d)); Assert.NotEqual(0, key.Kid.EncodedUtf8Bytes.Length); key = ECJwk.FromByteArray(EllipticalCurve.P256, x: x, y: y, d: d, KeyManagementAlgorithm.EcdhEs, computeThumbprint: false); Assert.True(key.X.SequenceEqual(x)); Assert.True(key.Y.SequenceEqual(y)); Assert.True(key.D.SequenceEqual(d)); Assert.Equal(0, key.Kid.EncodedUtf8Bytes.Length); key = ECJwk.FromByteArray(EllipticalCurve.P256, x: x, y: y, SignatureAlgorithm.ES256, computeThumbprint: true); Assert.True(key.X.SequenceEqual(x)); Assert.True(key.Y.SequenceEqual(y)); Assert.Equal(0, key.D.Length); Assert.NotEqual(0, key.Kid.EncodedUtf8Bytes.Length); key = ECJwk.FromByteArray(EllipticalCurve.P256, x: x, y: y, SignatureAlgorithm.ES256, computeThumbprint: false); Assert.True(key.X.SequenceEqual(x)); Assert.True(key.Y.SequenceEqual(y)); Assert.Equal(0, key.D.Length); Assert.Equal(0, key.Kid.EncodedUtf8Bytes.Length); key = ECJwk.FromByteArray(EllipticalCurve.P256, x: x, y: y, d: d, SignatureAlgorithm.ES256, computeThumbprint: true); Assert.True(key.X.SequenceEqual(x)); Assert.True(key.Y.SequenceEqual(y)); Assert.True(key.D.SequenceEqual(d)); Assert.NotEqual(0, key.Kid.EncodedUtf8Bytes.Length); key = ECJwk.FromByteArray(EllipticalCurve.P256, x: x, y: y, d: d, SignatureAlgorithm.ES256, computeThumbprint: false); Assert.True(key.X.SequenceEqual(x)); Assert.True(key.Y.SequenceEqual(y)); Assert.True(key.D.SequenceEqual(d)); Assert.Equal(0, key.Kid.EncodedUtf8Bytes.Length); }
// SEQUENCE // INTEGER 1 // OCTET STRING private key // [0] // OBJECT IDENTIFIER 1.2.840.10045.3.1.7 // [1] // BIT STRING public key public static ECJwk ReadECPrivateKey(string key) { string base64KeyData = key.Substring(PrivateECKeyPrefix.Length, key.Length - PrivateECKeyPrefix.Length - PrivateECKeySuffix.Length); byte[] keyData = Convert.FromBase64String(base64KeyData); var reader = new AsnReader(keyData); reader = reader.ReadSequence(); var version = reader.ReadInteger(); if (version.Length != 1 || version[0] != 1) { ThrowHelper.ThrowInvalidOperationException_InvalidPem(); } var privateKey = reader.ReadOctetStringBytes().ToArray(); var readerOid = reader.ReadSequence(true); var curveOid = readerOid.ReadOid(); reader = reader.ReadSequence(true); var publicKey = reader.ReadBitStringBytes(); if (publicKey.IsEmpty) { ThrowHelper.ThrowInvalidOperationException_InvalidPem(); } if (publicKey[0] != 0x04) { ThrowHelper.ThrowInvalidOperationException_InvalidPem(); } if (publicKey.Length != 2 * privateKey.Length + 1) { ThrowHelper.ThrowInvalidOperationException_InvalidPem(); } var x = publicKey.Slice(1, privateKey.Length).ToArray(); var y = publicKey.Slice(1 + privateKey.Length).ToArray(); if (reader.Read()) { ThrowHelper.ThrowInvalidOperationException_InvalidPem(); } if (Pkcs8.IsP256(curveOid)) { return(ECJwk.FromByteArray(EllipticalCurve.P256, d: privateKey, x: x, y: y)); } else if (Pkcs8.IsP384(curveOid)) { return(ECJwk.FromByteArray(EllipticalCurve.P384, d: privateKey, x: x, y: y)); } else if (Pkcs8.IsP521(curveOid)) { return(ECJwk.FromByteArray(EllipticalCurve.P521, d: privateKey, x: x, y: y)); } else { throw new NotSupportedException(); } }
// SEQUENCE // INTEGER 0 // SEQUENCE // OBJECT IDENTIFIER 1.2.840.10045.2.1 // OBJECT IDENTIFIER EC curve OID // OCTET STRING // SEQUENCE // INTEGER 1 // OCTET STRING private key // [1] // BIT STRING public key private static ECJwk ReadECPrivateKey(ref AsnReader reader, int[] curveOid) { reader = reader.ReadOctetString(); reader = reader.ReadSequence(); var version = reader.ReadInteger(); if (version.Length != 1 || version[0] != 1) { ThrowHelper.ThrowInvalidOperationException_InvalidPem(); } var privateKey = reader.ReadOctetStringBytes().ToArray(); reader = reader.ReadSequence(true); var publicKey = reader.ReadBitStringBytes(); if (publicKey.IsEmpty) { ThrowHelper.ThrowInvalidOperationException_InvalidPem(); } if (publicKey[0] != 0x04) { ThrowHelper.ThrowInvalidOperationException_InvalidPem(); } if (publicKey.Length != 2 * privateKey.Length + 1) { ThrowHelper.ThrowInvalidOperationException_InvalidPem(); } var x = publicKey.Slice(1, privateKey.Length).ToArray(); var y = publicKey.Slice(1 + privateKey.Length).ToArray(); if (reader.Read()) { ThrowHelper.ThrowInvalidOperationException_InvalidPem(); } if (IsP256(curveOid)) { return(ECJwk.FromByteArray(EllipticalCurve.P256, d: privateKey, x: x, y: y)); } else if (IsP384(curveOid)) { return(ECJwk.FromByteArray(EllipticalCurve.P384, d: privateKey, x: x, y: y)); } else if (IsP521(curveOid)) { return(ECJwk.FromByteArray(EllipticalCurve.P521, d: privateKey, x: x, y: y)); } else { throw new NotSupportedException(); } }
// SEQUENCE // INTEGER 1 // OCTET STRING private key // [0] // OBJECT IDENTIFIER 1.2.840.10045.3.1.7 // [1] // BIT STRING public key public static ECJwk ReadECPrivateKey(ReadOnlySpan <char> key) { var data = key.Slice(PrivateECKeyPrefix.Length, key.Length - PrivateECKeyPrefix.Length - PrivateECKeySuffix.Length); byte[] tmpArray; Span <byte> keyData = tmpArray = ArrayPool <byte> .Shared.Rent(Base64.GetArraySizeRequiredToDecode(data.Length)); try { int length = Base64.Decode(data, keyData); var reader = new AsnReader(keyData.Slice(0, length)); reader = reader.ReadSequence(); var version = reader.ReadInteger(); if (version.Length != 1 || version[0] != 1) { ThrowHelper.ThrowInvalidOperationException_InvalidPem(); } var privateKey = reader.ReadOctetStringBytes().ToArray(); var readerOid = reader.ReadSequence(true); var curveOid = readerOid.ReadOid(); reader = reader.ReadSequence(true); var publicKey = reader.ReadBitStringBytes(); if (publicKey.IsEmpty) { ThrowHelper.ThrowInvalidOperationException_InvalidPem(); } if (publicKey[0] != 0x04) { ThrowHelper.ThrowInvalidOperationException_InvalidPem(); } if (publicKey.Length != 2 * privateKey.Length + 1) { ThrowHelper.ThrowInvalidOperationException_InvalidPem(); } var x = publicKey.Slice(1, privateKey.Length).ToArray(); var y = publicKey.Slice(1 + privateKey.Length).ToArray(); if (reader.Read()) { ThrowHelper.ThrowInvalidOperationException_InvalidPem(); } if (Pkcs8.IsP256(curveOid)) { return(ECJwk.FromByteArray(EllipticalCurve.P256, d: privateKey, x: x, y: y)); } else if (Pkcs8.IsP384(curveOid)) { return(ECJwk.FromByteArray(EllipticalCurve.P384, d: privateKey, x: x, y: y)); } else if (Pkcs8.IsP521(curveOid)) { return(ECJwk.FromByteArray(EllipticalCurve.P521, d: privateKey, x: x, y: y)); } else { throw new NotSupportedException(); } } finally { ArrayPool <byte> .Shared.Return(tmpArray); } }