示例#1
0
        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
        }
示例#2
0
    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));
    }
示例#3
0
        /// <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));
        }
示例#4
0
        /// <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();
            }
        }
示例#6
0
        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);
        }
示例#7
0
        /// <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);
        }
示例#8
0
        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);
        }
示例#9
0
        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();
            }
        }
示例#10
0
        /// <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()
示例#11
0
        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);
        }
示例#12
0
        /// <summary>デジタル署名を作成する</summary>
        /// <param name="data">デジタル署名を行なう対象データ</param>
        /// <returns>対象データに対してデジタル署名したデジタル署名部分のデータ</returns>
        public override byte[] Sign(byte[] data)
        {
            ECDsaCng aa = new ECDsaCng(this._privateKey);

            return(aa.SignData(data));
        }
示例#13
0
        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)");
                }
            }
        }
示例#14
0
 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);
     }
 }
示例#15
0
        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();
        }
示例#16
0
        /// <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.");
        }
示例#17
0
 public byte[] SignData(byte[] dataForSign)
 {
     return(EcDsaCng.SignData(dataForSign, HashAlgorithmName.SHA1));
 }
示例#18
0
        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;
                }
                }
            }
        }
示例#19
0
        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);
        }
示例#20
0
        // 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
示例#21
0
 /// <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));
 }