コード例 #1
0
ファイル: KeyProvider.cs プロジェクト: viruswevh/ObscurCore
        public KeyProvider(int keysToMake = 5)
        {
            var symKeys    = new List <SymmetricKey>();
            var ecKeypairs = new List <ECKeypair>();

            for (int i = 0; i < keysToMake; i++)
            {
                // Symmetric key
                var newSymKey    = new byte[128.BitsToBytes()];
                var newSymCanary = new byte[128.BitsToBytes()];
                StratCom.EntropySupplier.NextBytes(newSymKey);
                StratCom.EntropySupplier.NextBytes(newSymCanary);
                symKeys.Add(new SymmetricKey {
                    Key = newSymKey,
                    ConfirmationCanary = newSymCanary,
                    UsePermissions     = SymmetricKeyUsePermission.Encryption | SymmetricKeyUsePermission.Authentication,
                    ContextPermissions = KeyUseContextPermission.ManifestHeader | KeyUseContextPermission.PayloadItem
                });
                // EC key
                int       curveIndex = StratCom.EntropySupplier.Next(Athena.Cryptography.EllipticCurves.Count);
                string    curveName  = Athena.Cryptography.EllipticCurves.Keys.ElementAt(curveIndex);
                ECKeypair newEcKey   = KeypairFactory.GenerateECKeypair(curveName);
                ecKeypairs.Add(newEcKey);
            }

            SymmetricKeys = symKeys;
            EcKeypairs    = ecKeypairs;
        }
コード例 #2
0
ファイル: KeyProvider.cs プロジェクト: viruswevh/ObscurCore
 /// <summary>
 ///     Create a key provider with keys based off an existing key provider,
 ///     aimed at a sender-recipient relationship.
 /// </summary>
 /// <param name="other">Existing key provider to use as a basis for interoperability.</param>
 public KeyProvider(KeyProvider other)
 {
     SymmetricKeys = other.SymmetricKeys.Reverse().ToList();
     EcKeypairs    = other.EcKeypairs.Select(
         item => {
         ECKeypair newEcKeypair = KeypairFactory.GenerateECKeypair(item.CurveName);
         var newEcCanary        = new byte[128.BitsToBytes()];
         StratCom.EntropySupplier.NextBytes(newEcCanary);
         newEcKeypair.ConfirmationCanary = newEcCanary;
         return(newEcKeypair);
     }).ToList();
 }
コード例 #3
0
        public void DJB_Ed25519_Blake2B512()
        {
            byte[] data = TEST;

            var digest = new Blake2BDigest(512);
            var m      = new byte[digest.OutputSize];

            digest.BlockUpdate(data, 0, data.Length);
            digest.DoFinal(m, 0);

            ECKeypair keypair = KeypairFactory.GenerateECKeypair(DjbCurve.Ed25519.ToString());

            byte[] sig  = Ed25519.Sign(m, keypair.EncodedPrivateKey);
            bool   good = Ed25519.Verify(sig, m, keypair.EncodedPublicKey);

            Assert.IsTrue(good);
        }
コード例 #4
0
        /// <summary>
        ///     Calculate the shared secret in participant U's (initiator) role.
        /// </summary>
        /// <param name="recipientPublicKey">Public key of the recipient.</param>
        /// <param name="senderPrivateKey">Private key of the sender.</param>
        /// <param name="ephemeralSenderPublicKey">
        ///     Ephemeral public key to send to the responder (V, receiver). Output to this
        ///     parameter.
        /// </param>
        public static byte[] Initiate(ECKey recipientPublicKey, ECKey senderPrivateKey,
                                      out ECKey ephemeralSenderPublicKey)
        {
            if (recipientPublicKey.PublicComponent == false)
            {
                throw new ArgumentException("Recipient key is not public component.", "recipientPublicKey");
            }
            if (senderPrivateKey.PublicComponent)
            {
                throw new ArgumentException("Sender key not private component.", "senderPrivateKey");
            }

            ECKey Q_static_V = recipientPublicKey;
            ECKey d_static_U = senderPrivateKey;

            ECKeypair kp_ephemeral_U = KeypairFactory.GenerateECKeypair(senderPrivateKey.CurveName);
            ECKey     Q_ephemeral_U  = kp_ephemeral_U.ExportPublicKey();
            ECKey     d_ephemeral_U  = kp_ephemeral_U.GetPrivateKey();

            // Calculate shared ephemeral secret 'Ze'
            byte[] Ze = KeyAgreementFactory.CalculateEcdhcSecret(Q_static_V, d_ephemeral_U);
            // Calculate shared static secret 'Zs'
            byte[] Zs = KeyAgreementFactory.CalculateEcdhcSecret(Q_static_V, d_static_U);

            // Concatenate Ze and Zs byte strings to form shared secret, pre-KDF : Ze||Zs
            var Z = new byte[Ze.Length + Zs.Length];

            Ze.DeepCopy_NoChecks(0, Z, 0, Ze.Length);
            Zs.DeepCopy_NoChecks(0, Z, Ze.Length, Zs.Length);
            ephemeralSenderPublicKey = Q_ephemeral_U;

            // Zero intermediate secrets
            Ze.SecureWipe();
            Zs.SecureWipe();

            return(Z);
        }
コード例 #5
0
        /// <summary>
        ///     Create a new elliptic curve keypair.
        /// </summary>
        /// <param name="curveName">Name of the elliptic curve to use as the basis.</param>
        /// <returns>Elliptic curve keypair.</returns>
        public static ECKeypair GenerateECKeypair(string curveName, bool generateCanary = true)
        {
            ECKeypair keypair;

            if (curveName.Equals(DjbCurve.Curve25519.ToString()))
            {
                var privEntropy = new byte[Curve25519.PrivateKeySeedSizeInBytes];
                StratCom.EntropySupplier.NextBytes(privEntropy);
                byte[] privateKey = Curve25519.CreatePrivateKey(privEntropy);
                byte[] publicKey  = Curve25519.CreatePublicKey(privateKey);

                byte[] canary = null;
                if (generateCanary)
                {
                    canary = new byte[128.BitsToBytes()];
                    StratCom.EntropySupplier.NextBytes(canary);
                }

                keypair = new ECKeypair {
                    CurveProviderName  = "DJB",
                    CurveName          = DjbCurve.Curve25519.ToString(),
                    EncodedPublicKey   = publicKey,
                    EncodedPrivateKey  = privateKey,
                    UsePermissions     = AsymmetricKeyUsePermission.KeyAgreements,
                    ContextPermissions = KeyUseContextPermission.ManifestHeader,
                    ConfirmationCanary = canary
                };
                privEntropy.SecureWipe();
            }
            else if (curveName.Equals(DjbCurve.Ed25519.ToString()))
            {
                var privEntropy = new byte[Ed25519.PrivateKeySeedSizeInBytes];
                StratCom.EntropySupplier.NextBytes(privEntropy);
                byte[] privateKey = new byte[Ed25519.ExpandedPrivateKeySizeInBytes];
                byte[] publicKey  = new byte[Ed25519.PublicKeySizeInBytes];
                Ed25519.KeyPairFromSeed(out publicKey, out privateKey, privEntropy);

                byte[] canary = null;
                if (generateCanary)
                {
                    canary = new byte[128.BitsToBytes()];
                    StratCom.EntropySupplier.NextBytes(canary);
                }

                keypair = new ECKeypair {
                    CurveProviderName  = "DJB",
                    CurveName          = DjbCurve.Ed25519.ToString(),
                    EncodedPublicKey   = publicKey,
                    EncodedPrivateKey  = privateKey,
                    UsePermissions     = AsymmetricKeyUsePermission.KeyAgreements | AsymmetricKeyUsePermission.Signatures,
                    ContextPermissions = KeyUseContextPermission.ManifestHeader,
                    ConfirmationCanary = canary
                };
                privEntropy.SecureWipe();
            }
            else
            {
                ECPoint    Q;
                BigInteger d;
                GenerateECKeypair(curveName, out Q, out d);

                byte[] canary = null;
                if (generateCanary)
                {
                    canary = new byte[128.BitsToBytes()];
                    StratCom.EntropySupplier.NextBytes(canary);
                }

                keypair = new ECKeypair {
                    CurveProviderName  = EcInformationStore.GetProvider(curveName),
                    CurveName          = curveName,
                    EncodedPublicKey   = Q.GetEncoded(),
                    EncodedPrivateKey  = d.ToByteArray(),
                    UsePermissions     = AsymmetricKeyUsePermission.KeyAgreements | AsymmetricKeyUsePermission.Signatures,
                    ContextPermissions = KeyUseContextPermission.ManifestHeader,
                    ConfirmationCanary = canary
                };
            }

            return(keypair);
        }
コード例 #6
0
        /// <summary>
        ///     Generate a verified output of a function given the correct key, to be used as a key confirmation.
        ///     Uses confirmation canary.
        /// </summary>
        /// <param name="configuration">Configuration of the verification function.</param>
        /// <param name="senderKeypair">Sender keypair to generate a confirmation output verification for.</param>
        /// <param name="recipientKey">Recipient key to generate a confirmation output verification for.</param>
        /// <returns>Output of the verification function, given the correct key.</returns>
        /// <exception cref="ArgumentException">Key is null or zero-length.</exception>
        /// <seealso cref="SymmetricKey"/>
        /// <seealso cref="ECKeypair"/>
        /// <seealso cref="IPossessConfirmationCanary"/>
        public static byte[] GenerateVerifiedOutput(AuthenticationConfiguration configuration, ECKeypair senderKeypair, ECKey recipientKey)
        {
            Func <byte[], byte[]> validator = GetValidator(configuration, TagConstantBytes,
                                                           configuration.SerialiseDto());

            byte[] canary         = XorCanaryBytes(senderKeypair.ConfirmationCanary, recipientKey.ConfirmationCanary);
            byte[] verifiedOutput = validator(canary);

            Debug.Print(DebugUtility.CreateReportString("ConfirmationUtility", "GenerateVerifiedOutput",
                                                        "Verified output",
                                                        verifiedOutput.ToHexString()));

            return(verifiedOutput);
        }
コード例 #7
0
        /// <summary>
        ///     Determines which (if any) key is valid from a set of potential keys.
        /// </summary>
        /// <remarks>
        ///     Where appropriate, computes confirmations in parallel.
        /// </remarks>
        /// <param name="keyConfirmation">Key confirmation configuration.</param>
        /// <param name="verifiedOutput">Known/verified output of the function if correct key is input.</param>
        /// <param name="potentialSenderKeys">Set of potential public keys used by the sender.</param>
        /// <param name="ephemeralKey"></param>
        /// <param name="potentialRecipientKeys">Keys used by the recipient that the sender may have used.</param>
        /// <param name="senderKey">Output of the public key associated with the private key used by the sender.</param>
        /// <param name="recipientKeypair">Output of the keypair that contains the public key used by the sender.</param>
        /// <exception cref="ArgumentNullException">Some input argument is null.</exception>
        /// <exception cref="ConfigurationInvalidException">
        ///     Some aspect of configuration invalid - detailed inside exception message.
        /// </exception>
        /// <returns>Valid key, or null if none are validated as being correct.</returns>
        public static void ConfirmKeyFromCanary(AuthenticationConfiguration keyConfirmation,
                                                byte[] verifiedOutput, IEnumerable <ECKey> potentialSenderKeys, ECKey ephemeralKey,
                                                IEnumerable <ECKeypair> potentialRecipientKeys, out ECKey senderKey, out ECKeypair recipientKeypair)
        {
            if (keyConfirmation == null)
            {
                throw new ArgumentNullException("keyConfirmation", "No configuration supplied.");
            }
            if (ephemeralKey == null)
            {
                throw new ArgumentNullException("ephemeralKey", "No ephemeral key supplied.");
            }
            if (potentialSenderKeys == null)
            {
                throw new ArgumentNullException("potentialSenderKeys", "No potential sender keys supplied.");
            }
            if (ephemeralKey == null)
            {
                throw new ArgumentNullException("ephemeralKey", "No ephemeral key supplied.");
            }
            if (potentialRecipientKeys == null)
            {
                throw new ArgumentNullException("potentialRecipientKeys", "No potential recipient keys supplied.");
            }

            // We can determine which, if any, of the provided keys are capable of decrypting the manifest
            var viableSenderKeys = potentialSenderKeys.AsQueryExpr().Where(key =>
                                                                           key.CurveProviderName.Equals(ephemeralKey.CurveProviderName) &&
                                                                           key.CurveName.Equals(ephemeralKey.CurveName)).Run().ToArray();

            if (viableSenderKeys.Length == 0)
            {
                throw new ArgumentException(
                          "No viable sender keys found - curve provider and/or curve name do not match ephemeral key.",
                          "potentialSenderKeys");
            }

            var viableRecipientKeypairs = potentialRecipientKeys.AsQueryExpr().Where(key =>
                                                                                     key.CurveProviderName.Equals(ephemeralKey.CurveProviderName) &&
                                                                                     key.CurveName.Equals(ephemeralKey.CurveName)).Run().ToArray();

            if (viableRecipientKeypairs.Length == 0)
            {
                throw new ArgumentException(
                          "No viable recipient keys found - curve provider and/or curve name do not match ephemeral key.",
                          "potentialRecipientKeys");
            }

            Func <byte[], byte[]> validator = GetValidator(keyConfirmation, TagConstantBytes,
                                                           keyConfirmation.SerialiseDto(), verifiedOutput.Length);

            // Temporary variables to store output in (can't access 'out' parameters inside anonymous method body)
            ECKey     oSK  = null;
            ECKeypair oRKP = null;

            // See which mode (by-sender / by-recipient) is better to run in parallel
            if (viableRecipientKeypairs.Length > viableSenderKeys.Length)
            {
                Parallel.ForEach(viableRecipientKeypairs, (rKeypair, state) => {
                    foreach (ECKey sKey in viableSenderKeys)
                    {
                        byte[] canary        = XorCanaryBytes(sKey.ConfirmationCanary, rKeypair.ConfirmationCanary);
                        byte[] validationOut = validator(canary);
                        if (validationOut.SequenceEqual_ConstantTime(verifiedOutput))
                        {
                            oSK  = sKey;
                            oRKP = rKeypair;
                            state.Stop();
                        }
                    }
                });
            }
            else
            {
                Parallel.ForEach(viableSenderKeys, (sKey, state) => {
                    foreach (var rKeypair in viableRecipientKeypairs)
                    {
                        byte[] canary        = XorCanaryBytes(sKey.ConfirmationCanary, rKeypair.ConfirmationCanary);
                        byte[] validationOut = validator(canary);
                        if (validationOut.SequenceEqual_ConstantTime(verifiedOutput))
                        {
                            oSK  = sKey;
                            oRKP = rKeypair;
                            state.Stop();
                        }
                    }
                });
            }

            // Assign the outputs to the 'out' parameters
            senderKey        = oSK;
            recipientKeypair = oRKP;
        }