/// <inheritdoc />
        public byte[] ComputeHash(string contentToSign)
        {
            var inputBytes = Encoding.UTF8.GetBytes(contentToSign);

            HashAlgorithm hasher = null;

            try {
                hasher = _hasherPool.Get();
                var hashedData = hasher.ComputeHash(inputBytes);
                return(_ecdsa.SignHash(hashedData));
            }
            finally {
                if (hasher != null)
                {
                    _hasherPool.Return(hasher);
                }
            }
        }
Пример #2
0
        public void SignVerify_InteroperableSameKeys_RoundTripsUnlessTampered(ECDsa ecdsa, HashAlgorithmName hashAlgorithm)
        {
            // large enough to make hashing work though multiple iterations and not a multiple of 4KB it uses.
            byte[] dataArray = new byte[33333];

            byte[] dataArray2 = new byte[dataArray.Length + 2];
            dataArray.CopyTo(dataArray2, 1);

            using HashAlgorithm halg =
                      hashAlgorithm == HashAlgorithmName.MD5 ? MD5.Create() :
                      hashAlgorithm == HashAlgorithmName.SHA1 ? SHA1.Create() :
                      hashAlgorithm == HashAlgorithmName.SHA256 ? SHA256.Create() :
                      hashAlgorithm == HashAlgorithmName.SHA384 ? SHA384.Create() :
                      hashAlgorithm == HashAlgorithmName.SHA512 ? SHA512.Create() :
                      throw new Exception("Hash algorithm not supported.");

            List <byte[]> signatures = new List <byte[]>(6);

            // Compute a signature using each of the SignData overloads.  Then, verify it using each
            // of the VerifyData overloads, and VerifyHash overloads.
            //
            // Then, verify that VerifyHash fails if the data is tampered with.

            signatures.Add(SignData(ecdsa, dataArray, hashAlgorithm));

            signatures.Add(ecdsa.SignHash(halg.ComputeHash(dataArray)));

            foreach (byte[] signature in signatures)
            {
                Assert.True(VerifyData(ecdsa, dataArray, signature, hashAlgorithm), "Verify 1");
                Assert.True(ecdsa.VerifyHash(halg.ComputeHash(dataArray), signature), "Verify 4");
            }

            int distinctSignatures = signatures.Distinct(new ByteArrayComparer()).Count();

            Assert.True(distinctSignatures == signatures.Count, "Signing should be randomized");

            foreach (byte[] signature in signatures)
            {
                signature[signature.Length - 1] ^= 0xFF; // flip some bits
                Assert.False(VerifyData(ecdsa, dataArray, signature, hashAlgorithm), "Verify Tampered 1");
                Assert.False(ecdsa.VerifyHash(halg.ComputeHash(dataArray), signature), "Verify Tampered 4");
            }
        }
            public override byte[] CreateSignature(byte[] rgbHash)
            {
                if (rgbHash == null)
                {
                    throw new ArgumentNullException("rgbHash");
                }

                if (m_key == null)
                {
                    throw new Exception("Must initialize key before creating a signature");
                }

                if (m_hashAlgorithm == null)
                {
                    throw new Exception("Must initialize hash algorithm before creating a signature");
                }

                byte[] signature = m_key.SignHash(rgbHash);
                return(signature);
            }
    public static byte[] ECDsaSignHash(BigInteger privateKey, byte[] hash)
    {
        if (!IsPrivateKeyValid(privateKey))
        {
            throw new Exception("privateKey is invalid.");
        }

        ECDsa        ecdsa      = ECDsa.Create(ECCurve.CreateFromFriendlyName("secp256k1"));    // windows 10: https://docs.microsoft.com/en-us/windows/desktop/SecCNG/cng-named-elliptic-curves
        ECParameters parameters = ecdsa.ExportExplicitParameters(true);

        parameters.D = Encode.BigIntegerToBytes(privateKey, 32);
        // parameters.Q is not used in SignHash
        ecdsa.ImportParameters(parameters);

        while (true)
        {
            byte[] sig = ecdsa.SignHash(hash);  // 64 bytes

            if (sig[32] < 0x7f)                 // low s value
            {
                return(sig);
            }
        }
    }
Пример #5
0
        public void SignVerify_InteroperableSameKeys_RoundTripsUnlessTampered(ECDsa ecdsa, HashAlgorithmName hashAlgorithm)
        {
            byte[] data = Encoding.UTF8.GetBytes("something to repeat and sign");

            // large enough to make hashing work though multiple iterations and not a multiple of 4KB it uses.
            byte[]       dataArray  = new byte[33333];
            MemoryStream dataStream = new MemoryStream(dataArray, true);

            while (dataStream.Position < dataArray.Length - data.Length)
            {
                dataStream.Write(data, 0, data.Length);
            }

            dataStream.Position = 0;

            byte[] dataArray2 = new byte[dataArray.Length + 2];
            dataArray.CopyTo(dataArray2, 1);
            ArraySegment <byte> dataSpan = new ArraySegment <byte>(dataArray2, 1, dataArray.Length);

            HashAlgorithm halg;

            if (hashAlgorithm == HashAlgorithmName.MD5)
            {
                halg = MD5.Create();
            }
            else if (hashAlgorithm == HashAlgorithmName.SHA1)
            {
                halg = SHA1.Create();
            }
            else if (hashAlgorithm == HashAlgorithmName.SHA256)
            {
                halg = SHA256.Create();
            }
            else if (hashAlgorithm == HashAlgorithmName.SHA384)
            {
                halg = SHA384.Create();
            }
            else if (hashAlgorithm == HashAlgorithmName.SHA512)
            {
                halg = SHA512.Create();
            }
            else
            {
                throw new Exception("Hash algorithm not supported.");
            }

            List <byte[]> signatures = new List <byte[]>(6);

            // Compute a signature using each of the SignData overloads.  Then, verify it using each
            // of the VerifyData overloads, and VerifyHash overloads.
            //
            // Then, verify that VerifyHash fails if the data is tampered with.

            signatures.Add(ecdsa.SignData(dataArray, hashAlgorithm));

            signatures.Add(ecdsa.SignData(dataSpan.Array, dataSpan.Offset, dataSpan.Count, hashAlgorithm));

            signatures.Add(ecdsa.SignData(dataStream, hashAlgorithm));
            dataStream.Position = 0;

            signatures.Add(ecdsa.SignHash(halg.ComputeHash(dataArray)));

            signatures.Add(ecdsa.SignHash(halg.ComputeHash(dataSpan.Array, dataSpan.Offset, dataSpan.Count)));

            signatures.Add(ecdsa.SignHash(halg.ComputeHash(dataStream)));
            dataStream.Position = 0;

            foreach (byte[] signature in signatures)
            {
                Assert.True(ecdsa.VerifyData(dataArray, signature, hashAlgorithm), "Verify 1");

                Assert.True(ecdsa.VerifyData(dataSpan.Array, dataSpan.Offset, dataSpan.Count, signature, hashAlgorithm), "Verify 2");

                Assert.True(ecdsa.VerifyData(dataStream, signature, hashAlgorithm), "Verify 3");
                Assert.True(dataStream.Position == dataArray.Length, "Check stream read 3A");
                dataStream.Position = 0;

                Assert.True(ecdsa.VerifyHash(halg.ComputeHash(dataArray), signature), "Verify 4");

                Assert.True(ecdsa.VerifyHash(halg.ComputeHash(dataSpan.Array, dataSpan.Offset, dataSpan.Count), signature), "Verify 5");

                Assert.True(ecdsa.VerifyHash(halg.ComputeHash(dataStream), signature), "Verify 6");
                Assert.True(dataStream.Position == dataArray.Length, "Check stream read 6A");
                dataStream.Position = 0;
            }

            int distinctSignatures = signatures.Distinct(new ByteArrayComparer()).Count();

            Assert.True(distinctSignatures == signatures.Count, "Signing should be randomized");

            foreach (byte[] signature in signatures)
            {
                signature[signature.Length - 1] ^= 0xFF; // flip some bits

                Assert.False(ecdsa.VerifyData(dataArray, signature, hashAlgorithm), "Verify Tampered 1");

                Assert.False(ecdsa.VerifyData(dataSpan.Array, dataSpan.Offset, dataSpan.Count, signature, hashAlgorithm), "Verify Tampered 2");

                Assert.False(ecdsa.VerifyData(dataStream, signature, hashAlgorithm), "Verify Tampered 3");
                Assert.True(dataStream.Position == dataArray.Length, "Check stream read 3B");
                dataStream.Position = 0;

                Assert.False(ecdsa.VerifyHash(halg.ComputeHash(dataArray), signature), "Verify Tampered 4");

                Assert.False(ecdsa.VerifyHash(halg.ComputeHash(dataSpan.Array, dataSpan.Offset, dataSpan.Count), signature), "Verify Tampered 5");

                Assert.False(ecdsa.VerifyHash(halg.ComputeHash(dataStream), signature), "Verify Tampered 6");
                Assert.True(dataStream.Position == dataArray.Length, "Check stream read 6B");
                dataStream.Position = 0;
            }
        }
Пример #6
0
 public void SignHash_NullHash_ThrowsArgumentNullException(ECDsa ecdsa)
 {
     AssertExtensions.Throws <ArgumentNullException>(
         "hash",
         () => ecdsa.SignHash(null));
 }
 private byte[] SignWithECDsa(byte[] bytes)
 {
     return(ECDsa.SignHash(HashAlgorithm.ComputeHash(bytes)));
 }
Пример #8
0
 protected override byte[] SignHash(ECDsa ecdsa, byte[] hash, int offset, int count) =>
 ecdsa.SignHash(new ReadOnlySpan <byte>(hash, offset, count));
Пример #9
0
 protected override byte[] SignHash(ECDsa ecdsa, byte[] hash, int offset, int count) =>
 WithOutputArray(dest => ecdsa.SignHash(new ReadOnlySpan <byte>(hash, offset, count), dest));
Пример #10
0
 public byte[] Sign(byte[] digest)
 {
     return(_key.SignHash(digest));
 }
Пример #11
0
 public byte[] Sign(byte[] hash)
 {
     return(_signer.SignHash(hash));
 }
Пример #12
0
 //ECDSA doesn't have the PKCS#1 / PSS hashing problem, so the hash is thrown away.
 public byte[] SignDigest(byte[] digest, HashAlgorithmName pkcsAlgorithm) => _algorithm.SignHash(digest);
Пример #13
0
        private static void RequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
        {
            string     key      = args.Request.Message.First().Key;
            string     value    = args.Request.Message.First().Value.ToString();
            JsonObject request  = JsonValue.Parse(value).GetObject();
            JsonObject response = new JsonObject
            {
                { "api", JsonValue.CreateNumberValue(1) },
                { "result", JsonValue.CreateStringValue("ok") }
            };

            if (request.ContainsKey("nonce"))
            {
                response.Add("nonce", request.GetNamedValue("nonce"));
            }
            switch (request.GetNamedString("type"))
            {
            case "VERSION":
                PackageVersion version = Package.Current.Id.Version;
                response.Add("version", JsonValue.CreateStringValue(
                                 string.Format("{0}.{1}.{2}.{3}", version.Major, version.Minor, version.Build, version.Revision)));
                args.Request.SendResponseAsync(new ValueSet {
                    ["message"] = response.ToString()
                }).Completed += delegate { };
                break;

            case "CERT":
                try
                {
                    String info = "By selecting a certificate I accept that my name and personal ID code will be sent to service provider.";
                    switch (request.GetNamedString("lang").ToString())
                    {
                    case "et":
                    case "est": info = "Sertifikaadi valikuga nõustun oma nime ja isikukoodi edastamisega teenusepakkujale."; break;

                    case "lt":
                    case "lit": info = "Pasirinkdama(s) sertifikatą, aš sutinku, kad mano vardas, pavardė ir asmens kodas būtų perduoti e. paslaugos teikėjui."; break;

                    case "lv":
                    case "lat": info = "Izvēloties sertifikātu, es apstiprinu, ka mans vārds un personas kods tiks nosūtīts pakalpojuma sniedzējam."; break;

                    case "ru":
                    case "rus": info = "Выбирая сертификат, я соглащаюсь с тем, что мое имя и личный код будут переданы представителю услуг."; break;

                    default: break;
                    }
                    X509Certificate2Collection list = new X509Certificate2Collection();
                    using (X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
                    {
                        store.Open(OpenFlags.ReadOnly);
                        bool forSigning = request.GetNamedString("filter", "SIGN").ToString() != "AUTH";
                        foreach (X509Certificate2 x in store.Certificates.Find(X509FindType.FindByTimeValid, DateTime.Now, false))
                        {
                            List <X509KeyUsageExtension> extensions = x.Extensions.OfType <X509KeyUsageExtension>().ToList();
                            if (extensions.Any() && ((extensions[0].KeyUsages & X509KeyUsageFlags.NonRepudiation) > 0) == forSigning && HasHWToken(x))
                            {
                                list.Add(x);
                            }
                        }
                    }
                    if (list.Count > 0)
                    {
                        X509Certificate2Collection certs = X509Certificate2UI.SelectFromCollection(
                            list, "", info, X509SelectionFlag.SingleSelection);
                        if (certs.Count > 0)
                        {
                            response.Add("cert", JsonValue.CreateStringValue(ByteToString(certs[0].Export(X509ContentType.Cert), false)));
                        }
                        else
                        {
                            response["result"] = JsonValue.CreateStringValue("user_cancel");
                            response.Add("message", JsonValue.CreateStringValue("user_cancel"));
                        }
                    }
                    else
                    {
                        response["result"] = JsonValue.CreateStringValue("no_certificates");
                        response.Add("message", JsonValue.CreateStringValue("no_certificates"));
                    }
                }
                catch (Exception e)
                {
                    response["result"] = JsonValue.CreateStringValue("technical_error");
                    response.Add("message", JsonValue.CreateStringValue(e.Message));
                }
                args.Request.SendResponseAsync(new ValueSet {
                    ["message"] = response.ToString()
                }).Completed += delegate { };
                break;

            case "SIGN":
                try
                {
                    String info = request.GetNamedString("info", "");
                    if (info.Length > 500)
                    {
                        throw new ArgumentException("Info parameter longer than 500 chars");
                    }
                    if (info.Length > 0 && MessageBox.Show(info, "", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No)
                    {
                        throw new Exception("User cancelled");
                    }

                    X509Certificate2 cert = new X509Certificate2(StringToByte(request.GetNamedString("cert")));
                    if (cert == null)
                    {
                        throw new ArgumentException("Failed to parse certificate");
                    }
                    X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
                    store.Open(OpenFlags.ReadOnly);
                    X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindByThumbprint, cert.Thumbprint, false);
                    if (certs.Count == 0)
                    {
                        throw new ArgumentException("Failed to find certificate");
                    }
                    byte[] signature = null;
                    if (certs[0].PublicKey.Oid.Value.Equals("1.2.840.10045.2.1"))
                    {
                        using (ECDsa ecdsa = certs[0].GetECDsaPrivateKey())
                        {
                            if (ecdsa == null)
                            {
                                throw new ArgumentException("Failed to find certificate token");
                            }
                            signature = ecdsa.SignHash(StringToByte(request.GetNamedString("hash")));
                        }
                    }
                    else
                    {
                        using (RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)certs[0].PrivateKey)
                        {
                            if (rsa == null)
                            {
                                throw new ArgumentException("Failed to find certificate token");
                            }
                            signature = rsa.SignHash(StringToByte(request.GetNamedString("hash")),
                                                     CryptoConfig.MapNameToOID(request.GetNamedString("hashtype").Replace("-", "")));
                        }
                    }
                    if (signature == null)
                    {
                        throw new Exception("Failed to sign hash");
                    }
                    response.Add("signature", JsonValue.CreateStringValue(ByteToString(signature, false)));
                }
                catch (Exception e)
                {
                    if (e is ArgumentException || e is ArgumentNullException)
                    {
                        response["result"] = JsonValue.CreateStringValue("invalid_argument");
                    }
                    else if (e.Message.Contains("cancelled"))
                    {
                        response["result"] = JsonValue.CreateStringValue("user_cancel");
                    }
                    else
                    {
                        response["result"] = JsonValue.CreateStringValue("technical_error");
                    }
                    response.Add("message", JsonValue.CreateStringValue(e.Message));
                }
                args.Request.SendResponseAsync(new ValueSet {
                    ["message"] = response.ToString()
                }).Completed += delegate { };
                break;

            default:
                Application.Exit();
                break;
            }
        }
Пример #14
0
 public override byte[] SignHash(byte[] hash) => _impl.SignHash(hash);
Пример #15
0
 protected static byte[] SignData(ECDsa key, params byte[][] data)
 {
     byte[] hash = HashData(HashAlgorithmName.SHA256, data);
     return(key.SignHash(hash));
 }