public static byte[] Sign(byte[] message, byte[] prikey, byte[] pubkey) { var signer = SignerUtilities.GetSigner("SHA256withECDSA"); var curve = NistNamedCurves.GetByName("P-256"); var dom = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H); ECKeyParameters privateKeyParameters = new ECPrivateKeyParameters(new BigInteger(1, prikey), dom); signer.Init(true, privateKeyParameters); signer.BlockUpdate(message, 0, message.Length); var sig = signer.GenerateSignature(); return(TranscodeSignatureToConcat(sig, 64)); #if OLD_VERSION #if NET461 const int ECDSA_PRIVATE_P256_MAGIC = 0x32534345; prikey = BitConverter.GetBytes(ECDSA_PRIVATE_P256_MAGIC).Concat(BitConverter.GetBytes(32)).Concat(pubkey).Concat(prikey).ToArray(); using (CngKey key = CngKey.Import(prikey, CngKeyBlobFormat.EccPrivateBlob)) using (ECDsaCng ecdsa = new ECDsaCng(key)) { return(ecdsa.SignData(message, HashAlgorithmName.SHA256)); } #else using (var ecdsa = ECDsa.Create(new ECParameters { Curve = ECCurve.NamedCurves.nistP256, D = prikey, Q = new ECPoint { X = pubkey.Take(32).ToArray(), Y = pubkey.Skip(32).ToArray() } })) { return(ecdsa.SignData(message, HashAlgorithmName.SHA256)); } #endif #endif }
public static string createJcs(ECDsaCng ecKey, Dictionary <String, Object> document) { // Add signature object Dictionary <String, Object> signature = new Dictionary <String, Object>(); document[SIGNATURE_JSON] = signature; signature[ALGORITHM_JSON] = ES256_ALG; Dictionary <String, Object> publicKey = new Dictionary <String, Object>(); signature[PUBLIC_KEY_JSON] = publicKey; publicKey[TYPE_JSON] = EC_PUBLIC_KEY; publicKey[CURVE_JSON] = P_521_CRV; byte[] rawKey = ecKey.Key.Export(CngKeyBlobFormat.EccPublicBlob); byte[] coordinate = new byte[66]; Buffer.BlockCopy(rawKey, 8, coordinate, 0, 66); publicKey[X_JSON] = base64urlencode(coordinate); Buffer.BlockCopy(rawKey, 74, coordinate, 0, 66); publicKey[Y_JSON] = base64urlencode(coordinate); ecKey.HashAlgorithm = CngAlgorithm.Sha256; signature[VALUE_JSON] = base64urlencode(ecKey.SignData(Encoding.UTF8.GetBytes(new JavaScriptSerializer().Serialize(document)))); return(new JavaScriptSerializer().Serialize(document)); }
/// <summary> /// Sign with ECDsa encryption method with the generated ECDsa private key /// </summary> /// <param name="privateKeyStr"></param> /// <param name="signData"></param> /// <returns></returns> private String GetPrivateSignatureStr(string privateKeyStr, string signData) { var privateSignedData = string.Empty; #if NET472 // net core not support this try { byte[] keyBytes = Convert.FromBase64String(privateKeyStr); CngKey cng = CngKey.Import(keyBytes, CngKeyBlobFormat.Pkcs8PrivateBlob); ECDsaCng dsa = new ECDsaCng(cng) { HashAlgorithm = CngAlgorithm.Sha256 }; byte[] signDataBytes = signData.ToBytesUTF8(); privateSignedData = Convert.ToBase64String(dsa.SignData(signDataBytes)); } catch (CryptographicException e) { Console.WriteLine("Private signature error because: " + e.Message); } #endif return(privateSignedData); // net core //var ecDsa = ECDsa.Create(); //var ecParameters = new ECParameters(); //ecParameters.Curve = null; //ecParameters.D = null; //ecParameters.Q = null; //ecDsa.ImportParameters(ecParameters); //byte[] signDataBytes = signData.ToBytes(); //privateSignedData = Convert.ToBase64String(ecDsa.SignData(signDataBytes, HashAlgorithmName.SHA256)); }
/// <summary> /// Create a web token signed by an ECDSA certificate, this is the parsed version for increased efficiancy /// /// To create the signer <see cref="Kalix.ApiCrypto.EC.ECDSACertificateParser.ParsePrivateCertificate"/> /// </summary> /// <param name="claims">JSON serialisable data to be signed</param> /// <param name="signingCertificate">Certificate data to use for signing</param> /// <param name="extraHeaderClaims">Extra header params</param> /// <param name="payloadSerializerSettings"><see cref="JsonSerializerSettings"/> to be used for <paramref name="claims"/> serialization.</param> /// <param name="headerJson">[Output] the header json</param> /// <param name="payloadJson">[Output] the payload json</param> /// <returns>JWT token</returns> public static string EncodeUsingECDSA <T>(T claims, ECDsaCng signingCertificate, IDictionary <string, object> extraHeaderClaims, JsonSerializerSettings payloadSerializerSettings, out string headerJson) { if (claims == null) { throw new ArgumentNullException("claims"); } if (extraHeaderClaims == null) { extraHeaderClaims = new Dictionary <string, object>(); } extraHeaderClaims["alg"] = string.Format("ES{0}", signingCertificate.KeySize); if (payloadSerializerSettings == null) { payloadSerializerSettings = new JsonSerializerSettings(); } var segments = new List <string>(3); headerJson = JsonConvert.SerializeObject(extraHeaderClaims, payloadSerializerSettings); var headerBytes = Encoding.UTF8.GetBytes(headerJson); var payloadJson = JsonConvert.SerializeObject(claims, payloadSerializerSettings); var payloadBytes = Encoding.UTF8.GetBytes(payloadJson); segments.Add(Base64UrlEncode(headerBytes)); segments.Add(Base64UrlEncode(payloadBytes)); var stringToSign = string.Join(".", segments); var bytesToSign = Encoding.UTF8.GetBytes(stringToSign); var signature = signingCertificate.SignData(bytesToSign); segments.Add(Base64UrlEncode(signature)); return(string.Join(".", segments)); }
public string SignWithEllipseCurve(string serializedKeys, string combinedJwsNotSigned) { if (string.IsNullOrWhiteSpace(serializedKeys)) { throw new ArgumentNullException("serializedKeys"); } if (string.IsNullOrWhiteSpace(combinedJwsNotSigned)) { throw new ArgumentNullException("combinedJwsNotSigned"); } var cngKey = _cngKeySerializer.DeserializeCngKeyWithPrivateKey(serializedKeys); var plainTextBytes = Encoding.UTF8.GetBytes(combinedJwsNotSigned); using (var ec = new ECDsaCng(cngKey)) { return(ec .SignData(plainTextBytes, 0, plainTextBytes.Count()) .Base64EncodeBytes()); // return ec.SignData(plainTextBytes).Base64EncodeBytes(); } }
public static string SignTransaction(Transaction transaction, long transactionInIndex, string privateKey, UnspentTransactionOut[] unspentTransactionsOut) { TransactionIn transactionIn = transaction.TransactionsIn[transactionInIndex]; string dataToSign = transaction.Id; UnspentTransactionOut refUnspentTransaction = FindUnspentTxOut(transactionIn.TransactionOutId, transactionIn.TransactionOutIndex, unspentTransactionsOut).FirstOrDefault(); if (refUnspentTransaction == null) { throw new Exception("Could not find the referenced transaction out."); } var referencedAddress = refUnspentTransaction.Address; // Verify that the public key generated with the private key == referencedAddress, if false throw; string signature64; byte[] privateKeyBytes = Encoding.UTF8.GetBytes(privateKey); var publicKey = CngKey.Import(privateKeyBytes, CngKeyBlobFormat.EccFullPrivateBlob); using (ECDsaCng dsa = new ECDsaCng(publicKey)) { byte[] dataAsBytes = Encoding.UTF8.GetBytes(dataToSign); //CngProperty prop = new CngProperty("privateKey", privateKeyBytes, CngPropertyOptions.None); //dsa.Key.SetProperty(prop); byte[] signature = dsa.SignData(dataAsBytes); signature64 = Convert.ToBase64String(signature); } return(signature64); }
/// <summary> /// Sign with ECDsa encryption method with the generated ECDsa private key /// </summary> /// <param name="privateKeyStr"></param> /// <param name="signData"></param> /// <returns></returns> private String GetPrivateSignatureStr(string privateKeyStr, string signData) { var privateSignedData = string.Empty; try { byte[] keyBytes = Convert.FromBase64String(privateKeyStr); CngKey cng = CngKey.Import(keyBytes, CngKeyBlobFormat.Pkcs8PrivateBlob); ECDsaCng dsa = new ECDsaCng(cng) { HashAlgorithm = CngAlgorithm.Sha256 }; byte[] signDataBytes = Encoding.UTF8.GetBytes(signData); privateSignedData = Convert.ToBase64String(dsa.SignData(signDataBytes)); } catch (CryptographicException e) { Console.WriteLine("Private signature error because: " + e.Message); } return(privateSignedData); }
string GetOrGenerateJwt() { if (_lastJwtGenerationTime > DateTime.UtcNow - TimeSpan.FromMinutes(20)) // refresh no more than once every 20 minutes { return(_jwt); } var now = DateTimeOffset.UtcNow; string header = JsonConvert.SerializeObject((new { alg = "ES256", kid = _keyId })); string payload = JsonConvert.SerializeObject(new { iss = _teamId, iat = now.ToUnixTimeSeconds() }); using (var dsa = new ECDsaCng(_key)) { dsa.HashAlgorithm = CngAlgorithm.Sha256; string headerBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(header)); string payloadBasae64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(payload)); string unsignedJwtData = $"{headerBase64}.{payloadBasae64}"; var signature = dsa.SignData(Encoding.UTF8.GetBytes(unsignedJwtData)); _jwt = $"{unsignedJwtData}.{Convert.ToBase64String(signature)}"; } _lastJwtGenerationTime = now.UtcDateTime; return(_jwt); }
public static void MainPack(bool create, string file, FileInfo fi, string packetName, bool isErrorDialog) { if (!create) { if (!File.Exists(file + ".pub") || !File.Exists(file + ".private")) { if (isErrorDialog) { MessageBox.Show("Извините, но данная пара ключей ещё не создана"); } else { Console.WriteLine("error: Извините, но данная пара ключей ещё не создана"); } return; } } var dn = fi.FullName; if (!fi.Exists || (fi.Attributes & FileAttributes.Directory) == 0) { dn = fi.DirectoryName; } var packetDirectory = new DirectoryInfo(dn).Parent; byte[] packet = pack(dn); if (create) { CngKeyCreationParameters keyCreateParms = new CngKeyCreationParameters(); keyCreateParms.ExportPolicy = CngExportPolicies.AllowPlaintextExport; using (CngKey DSKey = CngKey.Create(CngAlgorithm.ECDsaP521, null, keyCreateParms)) { byte[] dsKeyBlob; /*byte[] dsKeyBlob = DSKey.Export(CngKeyBlobFormat.Pkcs8PrivateBlob); * File.WriteAllBytes(file + ".private", dsKeyBlob);*/ dsKeyBlob = DSKey.Export(CngKeyBlobFormat.EccPrivateBlob); File.WriteAllBytes(file + ".private", dsKeyBlob); dsKeyBlob = DSKey.Export(CngKeyBlobFormat.EccPublicBlob); File.WriteAllBytes(file + ".pub", dsKeyBlob); } } if (!File.Exists(file + ".private")) { throw new FileNotFoundException(file + ".private"); } byte[] ecdsaSignature, ecdsaSignatureLower; using (CngKey DSKey = CngKey.Import(File.ReadAllBytes(file + ".private"), CngKeyBlobFormat.EccPrivateBlob)) { using (var ecdsa = new ECDsaCng(DSKey)) { ecdsa.HashAlgorithm = CngAlgorithm.Sha512; ecdsaSignature = ecdsa.SignData(packet); ecdsa.HashAlgorithm = CngAlgorithm.MD5; ecdsaSignatureLower = ecdsa.SignData(packet); } } using (var resultStream = new MemoryStream()) { var headSignature = Encoding.UTF8.GetBytes("\r\nFDSC PACK / prg.8vs.ru\r\n"); var keyName = Encoding.UTF8.GetBytes(file); int size = 8 + 4 + headSignature.Length + 4 + keyName.Length + 4 + ecdsaSignature.Length + 4 + ecdsaSignatureLower.Length + 4 + packet.Length; writeInt(resultStream, size); writeInt(resultStream, 0 + 4 + headSignature.Length + 4 + keyName.Length + 4 + ecdsaSignature.Length + 4 + ecdsaSignatureLower.Length); // всё, что до размера пакета writeAllBytesWithLength(resultStream, headSignature); writeAllBytesWithLength(resultStream, keyName); writeAllBytesWithLength(resultStream, ecdsaSignature); writeAllBytesWithLength(resultStream, ecdsaSignatureLower); writeAllBytesWithLength(resultStream, packet); var result = resultStream.ToArray(); if (result.Length != size) { throw new Exception("Что-то общий размер файла неправильно посчитался..."); } var n = DateTime.Now; File.WriteAllBytes( Path.Combine(packetDirectory.FullName, packetName + "-" + n.Year.ToString("D4") + n.Month.ToString("D2") + n.Day.ToString("D2") + ".updt"), result ); resultStream.Close(); } }
/// <summary> /// Sign using a non-default hash algorithm. /// </summary> /// <param name="data"></param> /// <param name="sigHash"></param> /// <returns></returns> public ISignatureUnion SignData(byte[] data, TpmAlgId sigHash) { #if TSS_USE_BCRYPT Debug.Assert(Key != UIntPtr.Zero); #endif var rsaParams = PublicParms.parameters as RsaParms; if (rsaParams != null) { #if !TSS_USE_BCRYPT Debug.Assert(RsaProvider != null); #endif TpmAlgId sigScheme = rsaParams.scheme.GetUnionSelector(); switch (sigScheme) { case TpmAlgId.Rsassa: { if (sigHash == TpmAlgId.Null) { sigHash = (rsaParams.scheme as SigSchemeRsassa).hashAlg; } byte[] digest = CryptoLib.HashData(sigHash, data); #if TSS_USE_BCRYPT byte[] sig = Key.SignHash(digest, BcryptScheme.Rsassa, sigHash); #else byte[] sig = RsaProvider.SignData(data, CryptoLib.GetHashName(sigHash)); #endif return(new SignatureRsassa(sigHash, sig)); } case TpmAlgId.Rsapss: { #if true Globs.Throw <ArgumentException>("SignData(): PSS scheme is not supported"); return(null); #else if (sigHash == TpmAlgId.Null) { sigHash = (rsaParams.scheme as SigSchemeRsapss).hashAlg; } #if TSS_USE_BCRYPT byte[] sig = BCryptInterface.SignHash(KeyHandle, digest, sigHash, false); #else var rr = new RawRsa(RsaProvider.ExportParameters(false), RsaProvider.KeySize); byte[] sig = rr.PssSign(digest, sigHash); #endif return(new SignatureRsapss(sigHash, sig)); #endif // false } } Globs.Throw <ArgumentException>("Unsupported signature scheme"); return(null); } var eccParms = PublicParms.parameters as EccParms; if (eccParms != null) { if (eccParms.scheme.GetUnionSelector() != TpmAlgId.Ecdsa) { Globs.Throw <ArgumentException>("Unsupported ECC sig scheme"); return(null); } if (sigHash == TpmAlgId.Null) { sigHash = (eccParms.scheme as SigSchemeEcdsa).hashAlg; } byte[] digest = CryptoLib.HashData(sigHash, data); #if TSS_USE_BCRYPT //throw new NotImplementedException("ECC signing with BCrypt is not implemented"); byte[] sig = Key.SignHash(digest, BcryptScheme.Ecdsa, sigHash); int len = sig.Length / 2; return(new SignatureEcdsa(sigHash, Globs.CopyData(sig, 0, len), Globs.CopyData(sig, len, len))); #elif !__MonoCS__ Debug.Assert(EcdsaProvider != null); EcdsaProvider.HashAlgorithm = GetCngAlgorithm(sigHash); byte[] sig = EcdsaProvider.SignData(data); int fragLen = sig.Length / 2; var r = Globs.CopyData(sig, 0, fragLen); var s = Globs.CopyData(sig, fragLen, fragLen); return(new SignatureEcdsa(sigHash, r, s)); #endif // !TSS_USE_BCRYPT && !__MonoCS__ } // Should never be here Globs.Throw("VerifySignature: Unrecognized asymmetric algorithm"); return(null); } // SignData()
internal async void MakeAssertionResponse(COSE.KeyType kty, COSE.Algorithm alg, COSE.EllipticCurve crv = COSE.EllipticCurve.P256) { const string rp = "fido2.azurewebsites.net"; byte[] rpId = System.Text.Encoding.UTF8.GetBytes(rp); var rpIdHash = SHA256.Create().ComputeHash(rpId); var flags = AuthenticatorFlags.AT | AuthenticatorFlags.ED | AuthenticatorFlags.UP | AuthenticatorFlags.UV; const UInt16 signCount = 0xf1d0; var aaguid = new Guid("F1D0F1D0-F1D0-F1D0-F1D0-F1D0F1D0F1D0"); var credentialID = new byte[] { 0xf1, 0xd0, 0xf1, 0xd0, 0xf1, 0xd0, 0xf1, 0xd0, 0xf1, 0xd0, 0xf1, 0xd0, 0xf1, 0xd0, 0xf1, 0xd0, }; CredentialPublicKey cpk = null; ECDsaCng ecdsa = null; RSACng rsa = null; byte[] privateKeySeed, publicKey, expandedPrivateKey = null; switch (kty) { case COSE.KeyType.EC2: { ecdsa = MakeECDsa(alg, crv); var ecparams = ecdsa.ExportParameters(true); cpk = MakeCredentialPublicKey(kty, alg, crv, ecparams.Q.X, ecparams.Q.Y); break; } case COSE.KeyType.RSA: { rsa = new RSACng(); var rsaparams = rsa.ExportParameters(true); cpk = MakeCredentialPublicKey(kty, alg, rsaparams.Modulus, rsaparams.Exponent); break; } case COSE.KeyType.OKP: { MakeEdDSA(out privateKeySeed, out publicKey, out expandedPrivateKey); cpk = MakeCredentialPublicKey(kty, alg, COSE.EllipticCurve.Ed25519, publicKey); break; } throw new ArgumentOutOfRangeException(string.Format("Missing or unknown kty {0}", kty.ToString())); } var acd = new AttestedCredentialData(aaguid, credentialID, cpk); var extBytes = CBORObject.NewMap().Add("testing", true).EncodeToBytes(); var exts = new Extensions(extBytes); var ad = new AuthenticatorData(rpIdHash, flags, signCount, acd, exts); var authData = ad.ToByteArray(); var challenge = new byte[128]; var rng = RandomNumberGenerator.Create(); rng.GetBytes(challenge); var clientData = new { Type = "webauthn.get", Challenge = challenge, Origin = rp, }; var clientDataJson = System.Text.Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(clientData)); var sha = SHA256.Create(); var hashedClientDataJson = sha.ComputeHash(clientDataJson); byte[] data = new byte[authData.Length + hashedClientDataJson.Length]; Buffer.BlockCopy(authData, 0, data, 0, authData.Length); Buffer.BlockCopy(hashedClientDataJson, 0, data, authData.Length, hashedClientDataJson.Length); byte[] signature = null; switch (kty) { case COSE.KeyType.EC2: { signature = ecdsa.SignData(data, CryptoUtils.algMap[(int)alg]); break; } case COSE.KeyType.RSA: { RSASignaturePadding padding; switch (alg) // https://www.iana.org/assignments/cose/cose.xhtml#algorithms { case COSE.Algorithm.PS256: case COSE.Algorithm.PS384: case COSE.Algorithm.PS512: padding = RSASignaturePadding.Pss; break; case COSE.Algorithm.RS1: case COSE.Algorithm.RS256: case COSE.Algorithm.RS384: case COSE.Algorithm.RS512: padding = RSASignaturePadding.Pkcs1; break; default: throw new ArgumentOutOfRangeException(string.Format("Missing or unknown alg {0}", alg.ToString())); } signature = rsa.SignData(data, CryptoUtils.algMap[(int)alg], padding); break; } case COSE.KeyType.OKP: { data = CryptoUtils.GetHasher(HashAlgorithmName.SHA512).ComputeHash(data); signature = Chaos.NaCl.Ed25519.Sign(data, expandedPrivateKey); break; } throw new ArgumentOutOfRangeException(string.Format("Missing or unknown kty {0}", kty.ToString())); } if (kty == COSE.KeyType.EC2) { signature = EcDsaSigFromSig(signature, ecdsa.KeySize); } var userHandle = new byte[16]; rng.GetBytes(userHandle); var assertion = new AuthenticatorAssertionRawResponse.AssertionResponse() { AuthenticatorData = authData, Signature = signature, ClientDataJson = clientDataJson, UserHandle = userHandle, }; var lib = new Fido2(new Fido2Configuration() { ServerDomain = rp, ServerName = rp, Origin = rp, }); List <PublicKeyCredentialDescriptor> existingCredentials = new List <PublicKeyCredentialDescriptor>(); var cred = new PublicKeyCredentialDescriptor(); cred.Type = PublicKeyCredentialType.PublicKey; cred.Id = new byte[] { 0xf1, 0xd0 }; existingCredentials.Add(cred); var options = lib.GetAssertionOptions(existingCredentials, null, null); options.Challenge = challenge; var response = new AuthenticatorAssertionRawResponse() { Response = assertion, Type = PublicKeyCredentialType.PublicKey, Id = new byte[] { 0xf1, 0xd0 }, RawId = new byte[] { 0xf1, 0xd0 }, }; IsUserHandleOwnerOfCredentialIdAsync callback = (args) => { return(Task.FromResult(true)); }; var res = await lib.MakeAssertionAsync(response, options, cpk.GetBytes(), signCount - 1, callback); }
/// <summary>デジタル署名を作成する</summary> /// <param name="data">デジタル署名を行なう対象データ</param> /// <returns>対象データに対してデジタル署名したデジタル署名部分のデータ</returns> public override byte[] Sign(byte[] data) { ECDsaCng aa = new ECDsaCng(this._privateKey); return(aa.SignData(data)); }
public static void TestVerify521_EcdhKey() { byte[] keyBlob = (byte[])TestData.s_ECDsa521KeyBlob.Clone(); // Rewrite the dwMagic value to be ECDH // ECDSA prefix: 45 43 53 36 // ECDH prefix : 45 43 4b 36 keyBlob[2] = 0x4b; using (CngKey ecdh521 = CngKey.Import(keyBlob, CngKeyBlobFormat.EccPrivateBlob)) { // Preconditions: Assert.Equal(CngAlgorithmGroup.ECDiffieHellman, ecdh521.AlgorithmGroup); Assert.Equal(CngAlgorithm.ECDiffieHellmanP521, ecdh521.Algorithm); using (ECDsa ecdsaFromEcdsaKey = new ECDsaCng(TestData.s_ECDsa521Key)) using (ECDsa ecdsaFromEcdhKey = new ECDsaCng(ecdh521)) { byte[] ecdhKeySignature = ecdsaFromEcdhKey.SignData(keyBlob, HashAlgorithmName.SHA512); byte[] ecdsaKeySignature = ecdsaFromEcdsaKey.SignData(keyBlob, HashAlgorithmName.SHA512); Assert.True( ecdsaFromEcdhKey.VerifyData(keyBlob, ecdsaKeySignature, HashAlgorithmName.SHA512), "ECDsaCng(ECDHKey) validates ECDsaCng(ECDsaKey)"); Assert.True( ecdsaFromEcdsaKey.VerifyData(keyBlob, ecdhKeySignature, HashAlgorithmName.SHA512), "ECDsaCng(ECDsaKey) validates ECDsaCng(ECDHKey)"); } } }
public Signature(CngKey key, byte[] data, int offset, int count) : this() { using (var dsa = new ECDsaCng(key)) { Buffer.BlockCopy(dsa.SignData(data, offset, count), 0, Bytes, 0, Length); } }
private static void Main(string[] args) { string hexPublic = "45435333300000007617E192615E8C24D353E8BD11DE21E9C54DC2D9D64C21AEC35A372B0EB3C205597BA20C0944FA6AFE871D23076F1D9711B5AAE0817BEAA6B953E9DF186B6BE1048050759005396B0A2856CF464C2E927916B0958CACEF8132A79C62456C8421"; string hexPrivate = "45435334300000007617E192615E8C24D353E8BD11DE21E9C54DC2D9D64C21AEC35A372B0EB3C205597BA20C0944FA6AFE871D23076F1D9711B5AAE0817BEAA6B953E9DF186B6BE1048050759005396B0A2856CF464C2E927916B0958CACEF8132A79C62456C842115772EBB4C4A3078DE768FCE8A8156380A6047E160BCFCAD24FB70416CFCCE0E693961D7C0F1198BA8B25CC2A6EF4C6D"; hexPublic = File.ReadAllLines(@"ServerCert\ECDSA.public")[0]; hexPrivate = File.ReadAllLines(@"ServerCert\ECDSAPrivate.key")[0]; string msg0 = "poruka"; byte[] data = Encoding.ASCII.GetBytes(msg0); var bytesKey = Enumerable.Range(0, hexPrivate.Length).Where(x => x % 2 == 0).Select(x => Convert.ToByte(hexPrivate.Substring(x, 2), 16)).ToArray(); CngKey key = CngKey.Import(bytesKey, CngKeyBlobFormat.EccPrivateBlob); /* * CngKey key = CngKey.Create(CngAlgorithm.ECDsaP384, null, new CngKeyCreationParameters { ExportPolicy = CngExportPolicies.AllowPlaintextExport }); * * var pubK = key.Export(CngKeyBlobFormat.EccPublicBlob); * var privK = key.Export(CngKeyBlobFormat.EccPrivateBlob); * * var hexpub = BitConverter.ToString(pubK).Replace("-", ""); * var hexpriv = BitConverter.ToString(privK).Replace("-", ""); */ ECDsaCng dsa = new ECDsaCng(key); String xmlExport = dsa.ToXmlString(ECKeyXmlFormat.Rfc4050); byte[] signature = dsa.SignData(data); /******************************/ var bytesKey2 = Enumerable.Range(0, hexPublic.Length).Where(x => x % 2 == 0).Select(x => Convert.ToByte(hexPublic.Substring(x, 2), 16)).ToArray(); CngKey key2 = CngKey.Import(bytesKey2, CngKeyBlobFormat.EccPublicBlob); ECDsaCng eccImporter = new ECDsaCng(key2); //eccImporter.FromXmlString(xmlExport, ECKeyXmlFormat.Rfc4050); if (eccImporter.VerifyData(data, signature)) { Console.WriteLine("Verified using .NET"); } #region early testing /* * * string msg = "The quick brown fox jumps over the lazy dog"; * string msg2 = "1vo je test"; * var a = Encoding.ASCII.GetBytes(msg); * var b = Encoding.ASCII.GetBytes(msg2); * var keey = makeGostKey(); * * var e1 = Compute_gost28147(a, keey); * var e2 = Compute_gost28147(b, keey); * * AsymmetricCipherKeyPair keyPair = ecdh_sha2_nistp521.getKeyPair(); * var o = keyPair.Public as ECPublicKeyParameters; * var ui = o.PublicKeyParamSet; * var senderPrivate = ((ECPrivateKeyParameters)keyPair.Private).D.ToByteArrayUnsigned(); * var senderPublic = ((ECPublicKeyParameters)keyPair.Public).Q.GetEncoded(); * * var p = (ECPrivateKeyParameters)PrivateKeyFactory.CreateKey(senderPrivate); * var pub = ((ECPublicKeyParameters)keyPair.Public).Q.ToString(); * var pub2 = BitConverter.ToString(senderPublic).Replace("-", "").ToLower(); * * var par = GenerateParameters(); * Debug.WriteLine(par.P.ToString()); * Debug.WriteLine(par.G.ToString()); * * TestBouncy(par); * //TestMethod(); * * Console.WriteLine("Server start call!"); * StartServer(); * * Thread.Sleep(1500); * Console.WriteLine("Klijent start call!"); * StartKlijent("pa kako je, ša ima?"); * */ #endregion early testing Console.ReadKey(); }
/// <summary> /// Calculate values for Diffie Hellman values /// </summary> /// <param name="sigmaSequenceCheck">Service Provider Sequence (State) Check</param> /// <param name="m1Received">Message 1</param> private void CalculateDiffieHellmanExchange(SpSequenceCheck sigmaSequenceCheck, M1RequestMessage m1Received) { log.Debug("CalculateDiffieHellmanExchange(..) started."); if (sigmaSequenceCheck == null || m1Received == null) { HttpResponseException e = new HttpResponseException(System.Net.HttpStatusCode.InternalServerError); options.LogThrownException(e); throw e; } // (Intel Performance Primitives) IPP Wrapper ippApiWrapper ippWrapper = new ippApiWrapper(); // Process message 1 and build the message 2 response. // Capture the GID and Base16 encode the gid field per the IAS API specificaiton: // "{gid} = Base 16-encoded representation of QE EPID group ID encoded as a Little Endian integer". // NOTE: This conversion assumes that the GID was sent without modification in the "pltfrmGid" message field. byte[] gidBa = m1Received.reqM1Body.pltfrmGid; // Required that the GID is supplied with no conversions from the SGX client and reverse the byte order // to convert to Big Endian integer for use later in the routine when encoding as a Base 16 string. Array.Reverse(gidBa); gidBaString = bMessage.BaToBlobStr(gidBa); // In crypto terms, a = Alice (Client) and b = Bob (Service provider) // so ga = secret shared by client and gb = secret shared by service provide gaLittleEndianstr = m1Received.GetGaString(); // Received in Little Endian format gaXLittleEndianstr = ""; // ga = gaX|gaY -- take the first half of ga to get gaX if (gaLittleEndianstr != null) { gaXLittleEndianstr = gaLittleEndianstr.Substring(0, gaLittleEndianstr.Length / 2); } gaXLittleEndian = bMessage.BlobStrToBa(gaXLittleEndianstr); gaXBigEndian = bMessage.BlobStrToBa(gaXLittleEndianstr); Array.Reverse(gaXBigEndian, 0, gaXBigEndian.Length); gaXBigEndianstr = bMessage.BaToBlobStr(gaXBigEndian); gaYLittleEndianstr = ""; if (gaLittleEndianstr != null) { gaYLittleEndianstr = gaLittleEndianstr.Substring(gaLittleEndianstr.Length / 2); } gaYLittleEndian = bMessage.BlobStrToBa(gaYLittleEndianstr); gaYBigEndian = bMessage.BlobStrToBa(gaYLittleEndianstr); Array.Reverse(gaYBigEndian, 0, gaYBigEndian.Length); gaYBigEndianstr = bMessage.BaToBlobStr(gaYBigEndian); // Capture the Little Endian representation of ga for later message checking sigmaSequenceCheck.currentGa = bMessage.BlobStrToBa(gaXLittleEndianstr + gaYLittleEndianstr); { // Use IPP or some other alternative if the user configuration does not select MS bcrypt for Diffie-Hellman key exchange. // NOTE: The use of IPP allows for the use of the standard wrapper functions in the SGX SDK. log.Debug("Calling IPP Wrapper for Diffie-Hellman key exchange..."); ippWrapper.InitDiffieHellman(); ippWrapper.GetDHPublicKey(ref gbXLittleEndian, ref gbYLittleEndian); gbXLittleEndianstr = bMessage.BaToBlobStr(gbXLittleEndian); gbYLittleEndianstr = bMessage.BaToBlobStr(gbYLittleEndian); gbLittleEndianStr = string.Concat(gbXLittleEndianstr, gbYLittleEndianstr); sigmaSequenceCheck.currentGb = bMessage.BlobStrToBa(gbXLittleEndianstr + gbYLittleEndianstr); log.DebugFormat("Server Public key: {0}", gbLittleEndianStr); // Derive the shared key byte[] sharedKey256 = new byte[Constants.SharedKeylen]; ippWrapper.GetDHSharedSecret(gaXLittleEndian, gaYLittleEndian, ref sharedKey256); derivedKeyStr = bMessage.BaToBlobStr(sharedKey256); log.DebugFormat("Shared secret: {0}", derivedKeyStr); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Use the full 256 bits of the derived DH key to further derive our smk //SMK is derived from the Diffie-Hellman shared secret elliptic curve field element // between the service provider and the // application enclave: // First compute Key Definition Key: KDK = AES-CMAC(0x00, gab x-coordinate) // Then SMK = AES-CMAC ( KDK, 0x01||’SMK’||0x00||0x80||0x00) byte[] derivedKeyBa = bMessage.BlobStrToBa(derivedKeyStr); // Store the KDK for further key derivation. sigmaSequenceCheck.currentKDK = cmacAES.Value(MsgInitValues.DS_ZERO_BA16, derivedKeyBa); // Store the SMK for the current session for use in processing message 3 sigmaSequenceCheck.currentSmk = bMessage.KeyLabelToKey(Constants.SMK, sigmaSequenceCheck.currentKDK); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Build each term by retrieving elements, // concatenating, converting and performing crypto operations. string gbgaStr = gbXLittleEndianstr + gbYLittleEndianstr + gaXLittleEndianstr + gaYLittleEndianstr; byte[] gbgaBa = bMessage.BlobStrToBa(gbgaStr); // gb||ga // Sign the gb||ga element Service Provider -- we use sigSP to notate this Service Provider signature // Get the Private Key from the settings file byte[] privateKey; try { privateKey = Constants.spPrivKeyBlob;// spPrivKeyBlob; } catch (Exception e) { options.LogCaughtErrorException(e); log.Debug("Failed to get private key: " + e.Message); HttpResponseException newException = new HttpResponseException(System.Net.HttpStatusCode.InternalServerError); options.LogThrownException(newException); throw newException; } CngKey signSgxKey = CngKey.Import(privateKey, CngKeyBlobFormat.EccPrivateBlob); ECDsaCng ecDsaSig = new ECDsaCng(signSgxKey); // Elliptic Curve Digital Signature Algorithm, Signature ecDsaSig.HashAlgorithm = CngAlgorithm.Sha256; byte[] sigSPpubKey = ecDsaSig.Key.Export(CngKeyBlobFormat.EccPublicBlob); string sigSPpubKeyBlob = "{ 0x" + BitConverter.ToString(sigSPpubKey).Replace("-", ", 0x") + " }"; byte[] sigSP = ecDsaSig.SignData(gbgaBa); // Input is LittleEndian, but output is BigEndian string sigSPstring = bMessage.BaToBlobStr(sigSP); // Separate the X and Y components of the signature -- Big Endian at this point string sigSPXBigEndianstr = sigSPstring.Substring(0, (sigSPstring.Length / 2)); byte[] sigSPXBigEndian = bMessage.BlobStrToBa(sigSPXBigEndianstr); string sigSPYBigEndianstr = sigSPstring.Substring(sigSPstring.Length / 2); byte[] sigSPYBigEndian = bMessage.BlobStrToBa(sigSPYBigEndianstr); // Swap the byte order of the signed data back to Little Endian and convert to combined string (X|Y) sigSPXLittleEndian = sigSPXBigEndian.Reverse().ToArray(); string sigSPXLittleEndianstr = bMessage.BaToBlobStr(sigSPXLittleEndian); sigSPYLittleEndian = sigSPYBigEndian.Reverse().ToArray(); string sigSPYLittleEndianstr = bMessage.BaToBlobStr(sigSPYLittleEndian); string sigSPLittleEndianstring = sigSPXLittleEndianstr + sigSPYLittleEndianstr; // sigSPLittleEndianstring is in Little Endian format as required, ready to send to client // Get the signature link type try { if (SpStartup.iasConnectionMgr.LinkableQuotes) { log.Debug("Using Linkable Quotes"); // If the SP policy setting dictates the use of linkable quotes, explicitly // overwrite the default value in the sltype container. // Otherwise, the default value will be an un-linkable quote type. System.Buffer.BlockCopy(Constants.linkableBa, 0, Constants.sltype, 0, Constants.linkableBa.Length); } } catch (Exception e) { options.LogCaughtErrorException(e); log.Debug("Failed to get Linked Quote: " + e.Message); HttpResponseException newException = new HttpResponseException(System.Net.HttpStatusCode.InternalServerError); options.LogThrownException(newException); throw newException; } string sigTypeStr = bMessage.BaToBlobStr(Constants.sltype); string kdfIdStr = bMessage.BaToBlobStr(Constants.kdfId); string gbSpidSigSPstring = gbLittleEndianStr + bMessage.BaToBlobStr(SpStartup.iasConnectionMgr.SPID) + sigTypeStr + kdfIdStr + sigSPLittleEndianstring; byte[] macBlob = bMessage.BlobStrToBa(gbSpidSigSPstring); // Compute the CMAKsmk of (gb||SPID||Type||KDF-ID||SigSP(gb||ga)) cMACsmk = cmacAES.Value(sigmaSequenceCheck.currentSmk, macBlob); string cMACsmkStr = bMessage.BaToBlobStr(cMACsmk); ecDsaSig.Dispose(); log.Debug("CalculateDiffieHellmanExchange(..) returning."); }
public byte[] SignData(byte[] dataForSign) { return(EcDsaCng.SignData(dataForSign, HashAlgorithmName.SHA1)); }
static void Main(string[] args) { //Clients.Add(IPAddress.Parse("192.168.43.174")); Clients.Add(IPAddress.Parse("192.168.43.153")); //Clients.Add(IPAddress.Parse("91.121.50.14")); Clients.Add(IPAddress.Parse("192.168.43.47")); //Clients.Add(IPAddress.Parse("192.168.43.41")); foreach (var ip in Discoverer.GetAllLocalIPv4()) { Clients.Add(ip); Console.WriteLine("Local IP: " + ip.ToString()); } Console.WriteLine("Starting node server..."); Task.Run(() => Serve()); Discoverer.PeerJoined = x => Connect(x); Discoverer.PeerLeft = x => Disconnect(x); Discoverer.Start(); Task.Delay(1000).Wait(); Task.Run(() => Update()); Task.Delay(1000).Wait(); if (!File.Exists("privatekey.txt")) { Console.WriteLine("Generating key..."); CngKeyCreationParameters keyCreationParameters = new CngKeyCreationParameters(); keyCreationParameters.ExportPolicy = CngExportPolicies.AllowPlaintextExport; keyCreationParameters.KeyUsage = CngKeyUsages.Signing; CngKey key = CngKey.Create(CngAlgorithm.ECDsaP256, null, keyCreationParameters); ECDsaCng dsa = new ECDsaCng(key); byte[] privateKey = dsa.Key.Export(CngKeyBlobFormat.EccPrivateBlob); File.WriteAllText("privatekey.txt", String.Join(",", privateKey)); } CngKey importedKey = CngKey.Import(File.ReadAllText("privatekey.txt").Split(',').Select(m => byte.Parse(m)).ToArray(), CngKeyBlobFormat.EccPrivateBlob); importedDSA = new ECDsaCng(importedKey); publicKey = importedDSA.Key.Export(CngKeyBlobFormat.EccPublicBlob); using (SHA1 sha1 = SHA1.Create()) { pubKeyHash = sha1.ComputeHash(publicKey); } Console.Write("Address: " + BitConverter.ToString(pubKeyHash).Replace("-", string.Empty)); Console.WriteLine(); var httpServer = new HttpServer(new HttpRequestProvider()); var lhgdkg = new TcpListener(IPAddress.Any, 80); //lhgdkg.Server.ReceiveTimeout = 10000; httpServer.Use(new TcpListenerAdapter(lhgdkg)); Thread abc = new Thread(_ => (new UI()).ShowDialog()); abc.Start(null); /*httpServer.Use((a, b) => { * * string ach = Program.template; * string data = ""; * foreach (var pair in Program.Balances) * { * data += "<tr><td>"; * data += BitConverter.ToString(pair.Key).Replace("-", string.Empty); * data += "</td><td>"; * data += pair.Value; * data += "</td></tr>"; * } * ach = ach.Replace("{data}", data); * while (true) * { * try * { * Thread.Sleep(100); * var tw = new StreamWriter("index.html"); * tw.Write(ach); * tw.Close(); * break; * } * catch { } * } * Thread.Sleep(100); * //File.WriteAllText("index.html", ach); * return b(); * });*/ httpServer.Use(new fix()); httpServer.Start(); while (true) { Console.Write("> "); string cmd = Console.ReadLine(); string[] command = cmd.Split(' '); switch (command[0]) { case "help": { Console.WriteLine("help : view help"); Console.WriteLine("tx <address> <amount> : send money"); Console.WriteLine("mine [threads] [address] : start/stop mining"); Console.WriteLine("bal [address] : view balance"); Console.WriteLine("exit : close the program"); break; } case "exit": { httpServer.Dispose(); Environment.Exit(0); break; } case "bal": { byte[] address = new byte[20]; if (command.Length > 1) { for (int i = 0; i < 20; i++) { address[i] = Convert.ToByte(command[1].Substring(i * 2, 2), 16); } } else { address = pubKeyHash; } double balance = 0; if (Balances.ContainsKey(address)) { balance = Balances[address]; } Console.WriteLine("Current balance: " + balance); break; } case "tx": { if (command.Length != 3) { Console.WriteLine("Missing arguments."); break; } if (command[1].Length != 40) { Console.WriteLine("Invalid address."); break; } byte[] addr = new byte[20]; int i = 0; for (; i < 20; i++) { try { addr[i] = Convert.ToByte(command[1].Substring(i * 2, 2), 16); } catch { Console.WriteLine("Invalid address."); break; } } if (i < 19) { break; } double amount = double.Parse(command[2]); var tx = new Transaction(); tx.target = addr; tx.amount = amount; tx.source = publicKey; tx.timestamp = (uint)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; tx.signature = importedDSA.SignData(tx.GetBytesToSign(), HashAlgorithmName.SHA256); IPEndPoint ipep2 = new IPEndPoint(IPAddress.Any, 53417); UdpClient newsock = new UdpClient(ipep2); newsock.Client.ReceiveTimeout = 1000; newsock.Client.SendTimeout = 1000; foreach (IPAddress ip in Clients) { if (Discoverer.GetAllLocalIPv4().Contains(ip)) { continue; } IPEndPoint ipep = new IPEndPoint(ip, 53418); byte[] data = null; byte[] transaction = tx.GetBytesTotal(); List <byte> packet = new List <byte>(); packet.Add(0x02); packet.AddRange(BitConverter.GetBytes((ushort)transaction.Length)); packet.AddRange(transaction); try { newsock.Send(packet.ToArray(), packet.Count, ipep); } catch { continue; } try { data = newsock.Receive(ref ipep); } catch { continue; } } newsock.Close(); Swarm.Add(tx); break; } case "mine": { ulong threads = 1; if (command.Length > 1) { threads = ulong.Parse(command[1]); } if (isMining) { Console.WriteLine("Stopped mining."); miningThreads.ForEach(x => x.Abort()); miningThreads.Clear(); } else { Console.WriteLine("Started mining."); ulong nonceOffset = ulong.MaxValue / threads; byte[] address = new byte[20]; if (command.Length > 2) { for (int i = 0; i < 20; i++) { address[i] = Convert.ToByte(command[2].Substring(i * 2, 2), 16); } } else { address = pubKeyHash; } Random r = new Random(); for (ulong i = 0; i < threads; i++) { Thread miningThread = new Thread((param) => Mine(address, (ulong)param)); byte[] nonce = new byte[8]; r.NextBytes(nonce); nonce[7] = (byte)i; miningThread.Start(BitConverter.ToUInt64(nonce, 0)); miningThreads.Add(miningThread); } } isMining = !isMining; break; } } } }
public async Task ECAsymmetricSigningAndEncryption() { var bob = new ECDsaCng(521); var bobPublic = CngKey.Import(bob.Key.Export(CngKeyBlobFormat.EccPublicBlob), CngKeyBlobFormat.EccPublicBlob); var alice = new ECDsaCng(521); var alicePublic = CngKey.Import(alice.Key.Export(CngKeyBlobFormat.EccPublicBlob), CngKeyBlobFormat.EccPublicBlob); // Bob formulates request. var bobRequest = new MemoryStream(); var bobDH = ECDiffieHellman.Create(); { byte[] bobPublicDH = bobDH.PublicKey.ToByteArray(); byte[] bobSignedDH = bob.SignData(bobPublicDH); await bobRequest.WriteSizeAndBufferAsync(bobPublicDH, CancellationToken.None); await bobRequest.WriteSizeAndBufferAsync(bobSignedDH, CancellationToken.None); bobRequest.Position = 0; } // Alice reads request. var aliceResponse = new MemoryStream(); byte[] aliceKeyMaterial; var aliceDH = new ECDiffieHellmanCng(); { byte[] bobPublicDH = await bobRequest.ReadSizeAndBufferAsync(CancellationToken.None); byte[] bobSignedDH = await bobRequest.ReadSizeAndBufferAsync(CancellationToken.None); var bobDsa = new ECDsaCng(bobPublic); Assert.IsTrue(bobDsa.VerifyData(bobPublicDH, bobSignedDH)); var bobDHPK = ECDiffieHellmanCngPublicKey.FromByteArray(bobPublicDH, CngKeyBlobFormat.EccPublicBlob); aliceKeyMaterial = aliceDH.DeriveKeyMaterial(bobDHPK); await aliceResponse.WriteSizeAndBufferAsync(aliceDH.PublicKey.ToByteArray(), CancellationToken.None); await aliceResponse.WriteSizeAndBufferAsync(alice.SignData(aliceDH.PublicKey.ToByteArray()), CancellationToken.None); // Alice also adds a secret message. using (var aes = SymmetricAlgorithm.Create()) { using (var encryptor = aes.CreateEncryptor(aliceKeyMaterial, new byte[aes.BlockSize / 8])) { var cipherText = new MemoryStream(); using (var cryptoStream = new CryptoStream(cipherText, encryptor, CryptoStreamMode.Write)) { cryptoStream.Write(new byte[] { 0x1, 0x3, 0x2 }, 0, 3); cryptoStream.FlushFinalBlock(); cipherText.Position = 0; await aliceResponse.WriteSizeAndStreamAsync(cipherText, CancellationToken.None); } } } aliceResponse.Position = 0; } // Bob reads response byte[] bobKeyMaterial; { byte[] alicePublicDH = await aliceResponse.ReadSizeAndBufferAsync(CancellationToken.None); byte[] aliceSignedDH = await aliceResponse.ReadSizeAndBufferAsync(CancellationToken.None); var aliceDsa = new ECDsaCng(alicePublic); Assert.IsTrue(aliceDsa.VerifyData(alicePublicDH, aliceSignedDH)); var aliceDHPK = ECDiffieHellmanCngPublicKey.FromByteArray(alicePublicDH, CngKeyBlobFormat.EccPublicBlob); bobKeyMaterial = bobDH.DeriveKeyMaterial(aliceDHPK); // And Bob reads Alice's secret message. using (var aes = SymmetricAlgorithm.Create()) { using (var decryptor = aes.CreateDecryptor(aliceKeyMaterial, new byte[aes.BlockSize / 8])) { var plaintext = new MemoryStream(); var substream = await aliceResponse.ReadSizeAndStreamAsync(CancellationToken.None); using (var cryptoStream = new CryptoStream(substream, decryptor, CryptoStreamMode.Read)) { await cryptoStream.CopyToAsync(plaintext); plaintext.Position = 0; byte[] secretMessage = new byte[1024]; int readBytes = plaintext.Read(secretMessage, 0, secretMessage.Length); } } } } CollectionAssert.AreEqual(aliceKeyMaterial, bobKeyMaterial); }
// http://crypto.stackexchange.com/questions/5646/what-are-the-differences-between-a-digital-signature-a-mac-and-a-hash // Integrity: Can the recipient be confident that the message has not been accidentally modified? // Authentication: Can the recipient be confident that the message originates from the sender? // Non-repudiation: If the recipient passes the message and the proof to a third party, // can the third party be confident that the message originated from the sender? // Cryptographic primitive | Hash | MAC | Digital // Security Goal | | | signature // ------------------------+------+-----------+------------- // Integrity | Yes | Yes | Yes // Authentication | No | Yes | Yes // Non-repudiation | No | No | Yes // ------------------------+------+-----------+------------- // Kind of keys | none | symmetric | asymmetric // | | keys | keys static JsonWebToken() { JsonSerializer = new DefaultJsonSerializer(); UnixEpoch = new System.DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc); // https://stackoverflow.com/questions/10055158/is-there-a-json-web-token-jwt-example-in-c // https://stackoverflow.com/questions/34403823/verifying-jwt-signed-with-the-rs256-algorithm-using-public-key-in-c-sharp // http://codingstill.com/2016/01/verify-jwt-token-signed-with-rs256-using-the-public-key/ HashAlgorithms = new System.Collections.Generic.Dictionary <JwtHashAlgorithm, GenericHashFunction_t> { { JwtHashAlgorithm.None, (key, value) => { throw new TokenAlgorithmRefusedException(); } }, { JwtHashAlgorithm.HS256, (key, value) => { using (HMACSHA256 sha = new HMACSHA256(key)) { return(sha.ComputeHash(value)); } } }, { JwtHashAlgorithm.HS384, (key, value) => { using (HMACSHA384 sha = new HMACSHA384(key)) { return(sha.ComputeHash(value)); } } }, { JwtHashAlgorithm.HS512, (key, value) => { using (HMACSHA512 sha = new HMACSHA512(key)) { return(sha.ComputeHash(value)); } } }, { JwtHashAlgorithm.RS256, (key, value) => { using (SHA256 sha = SHA256.Create()) { // https://github.com/mono/mono/blob/master/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetricsignatureformatter.cs // https://github.com/mono/mono/blob/master/mcs/class/corlib/System.Security.Cryptography/RSAPKCS1SignatureFormatter.cs // https://github.com/mono/mono/blob/master/mcs/class/Mono.Security/Mono.Security.Cryptography/PKCS1.cs using (RSACryptoServiceProvider rsa = RSA.PEM.CreateRsaProvider()) { // System.Security.Cryptography.RSAPKCS1SignatureFormatter RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(rsa); RSAFormatter.SetHashAlgorithm("SHA256"); //Create a signature for HashValue and return it. return(RSAFormatter.CreateSignature(sha.ComputeHash(value))); } } } } , { JwtHashAlgorithm.RS384, (key, value) => { using (SHA384 sha = System.Security.Cryptography.SHA384.Create()) { using (RSACryptoServiceProvider rsa = RSA.PEM.CreateRsaProvider()) { RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(rsa); RSAFormatter.SetHashAlgorithm("SHA384"); return(RSAFormatter.CreateSignature(sha.ComputeHash(value))); } } } } , { JwtHashAlgorithm.RS512, (key, value) => { using (SHA512 sha = System.Security.Cryptography.SHA512.Create()) { using (RSACryptoServiceProvider rsa = RSA.PEM.CreateRsaProvider()) { RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(rsa); RSAFormatter.SetHashAlgorithm("SHA512"); return(RSAFormatter.CreateSignature(sha.ComputeHash(value))); } } } } #if false // https://github.com/mono/mono/tree/master/mcs/class/referencesource/System.Core/System/Security/Cryptography // https://github.com/mono/mono/blob/master/mcs/class/referencesource/System.Core/System/Security/Cryptography/ECDsaCng.cs // https://github.com/mono/mono/blob/master/mcs/class/referencesource/System.Core/System/Security/Cryptography/ECDsa.cs // ECDsaCng => next generation cryptography // Is just a wrapper around ncrypt, plus some constructors throw on mono/netstandard... in short - horrible thing , { JwtHashAlgorithm.ES256, (key, value) => { // using (ECDsaCng ecd = new System.Security.Cryptography.ECDsaCng(256)) using (ECDsaCng ecd = RSA.PEM.CreateEcdProvider()) { ecd.HashAlgorithm = CngAlgorithm.Sha256; byte[] publickey = ecd.Key.Export(CngKeyBlobFormat.EccPublicBlob); return(ecd.SignData(value)); } } } , { JwtHashAlgorithm.ES384, (key, value) => { // using (ECDsaCng ecd = new System.Security.Cryptography.ECDsaCng(384)) using (ECDsaCng ecd = RSA.PEM.CreateEcdProvider()) { ecd.HashAlgorithm = CngAlgorithm.Sha384; return(ecd.SignData(value)); } } } , { JwtHashAlgorithm.ES512, (key, value) => { // using (ECDsaCng ecd = new System.Security.Cryptography.ECDsaCng(512)) using (ECDsaCng ecd = RSA.PEM.CreateEcdProvider()) { ecd.HashAlgorithm = CngAlgorithm.Sha512; return(ecd.SignData(value)); } } } #endif }; } // End Constructor
/// <summary> /// Signs a hash of the specified data and returns the signature. /// </summary> /// <param name="data"></param> /// <returns></returns> public byte[] Sign(byte[] data) { lock (dsa) return(dsa.SignData(data)); }