예제 #1
0
        protected void DecodeCertMono(McpeLogin message)
        {
            byte[] buffer = message.payload;

            if (message.payload.Length != buffer.Length)
            {
                Log.Debug($"Wrong lenght {message.payload.Length} != {message.payload.Length}");
                throw new Exception($"Wrong lenght {message.payload.Length} != {message.payload.Length}");
            }

            if (Log.IsDebugEnabled)
            {
                Log.Debug("Lenght: " + message.payload.Length + ", Message: " + buffer.EncodeBase64());
            }

            string certificateChain;
            string skinData;

            try
            {
                var destination = new MemoryStream(buffer);
                destination.Position = 0;
                NbtBinaryReader reader = new NbtBinaryReader(destination, false);

                var countCertData = reader.ReadInt32();
                certificateChain = Encoding.UTF8.GetString(reader.ReadBytes(countCertData));
                if (Log.IsDebugEnabled)
                {
                    Log.Debug($"Certificate Chain (Lenght={countCertData})\n{certificateChain}");
                }

                var countSkinData = reader.ReadInt32();
                skinData = Encoding.UTF8.GetString(reader.ReadBytes(countSkinData));
                if (Log.IsDebugEnabled)
                {
                    Log.Debug($"Skin data (Lenght={countSkinData})\n{skinData}");
                }
            }
            catch (Exception e)
            {
                Log.Error("Parsing login", e);
                return;
            }

            try
            {
                {
                    IDictionary <string, dynamic> headers = JWT.Headers(skinData);
                    dynamic payload = JObject.Parse(JWT.Payload(skinData));

                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug($"Skin JWT Header: {string.Join(";", headers)}");
                    }
                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug($"Skin JWT Payload:\n{payload.ToString()}");
                    }

                    try
                    {
                        _playerInfo.ClientId         = payload.ClientRandomId;
                        _playerInfo.CurrentInputMode = payload.CurrentInputMode;
                        _playerInfo.DefaultInputMode = payload.DefaultInputMode;
                        _playerInfo.DeviceModel      = payload.DeviceModel;
                        _playerInfo.DeviceOS         = payload.DeviceOS;
                        _playerInfo.GameVersion      = payload.GameVersion;
                        _playerInfo.GuiScale         = payload.GuiScale;
                        _playerInfo.LanguageCode     = payload.LanguageCode;
                        _playerInfo.ServerAddress    = payload.ServerAddress;
                        _playerInfo.UIProfile        = payload.UIProfile;

                        _playerInfo.Skin = new Skin()
                        {
                            CapeData         = Convert.FromBase64String((string)payload.CapeData),
                            SkinId           = payload.SkinId,
                            SkinData         = Convert.FromBase64String((string)payload.SkinData),
                            SkinGeometryName = payload.SkinGeometryName,
                            SkinGeometry     = Encoding.UTF8.GetString(Convert.FromBase64String((string)payload.SkinGeometry)),
                        };
                        Log.Warn($"Cape data lenght={_playerInfo.Skin.CapeData.Length}");
                    }
                    catch (Exception e)
                    {
                        Log.Error("Parsing skin data", e);
                    }
                }

                //var chainArray = chain.ToArray();

                string validationKey     = null;
                string identityPublicKey = null;
                //if (!isMono)
                {
                    dynamic json = JObject.Parse(certificateChain);

                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug($"Certificate JSON:\n{json}");
                    }

                    JArray chain = json.chain;

                    foreach (JToken token in chain)
                    {
                        IDictionary <string, dynamic> headers = JWT.Headers(token.ToString());

                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug("Raw chain element:\n" + token.ToString());
                            Log.Debug($"JWT Header: {string.Join(";", headers)}");

                            dynamic jsonPayload = JObject.Parse(JWT.Payload(token.ToString()));
                            Log.Debug($"JWT Payload:\n{jsonPayload}");
                        }

                        // Mojang root x5u cert (string): MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8ELkixyLcwlZryUQcu1TvPOmI2B7vX83ndnWRUaXm74wFfa5f/lwQNTfrLVHa2PmenpGI6JhIMUJaWZrjmMj90NoKNFSNBuKdm8rYiXsfaz3K36x/1U26HpG0ZxK/V1V

                        if (!headers.ContainsKey("x5u"))
                        {
                            continue;
                        }

                        string x5u = headers["x5u"];

                        if (identityPublicKey == null)
                        {
                            if (CertificateData.MojangRootKey.Equals(x5u, StringComparison.InvariantCultureIgnoreCase))
                            {
                                Log.Debug("Key is ok, and got Mojang root");
                            }
                            else if (chain.Count > 1)
                            {
                                Log.Debug("Got client cert (client root)");
                                continue;
                            }
                            else if (chain.Count == 1)
                            {
                                Log.Debug("Selfsigned chain");
                            }
                        }
                        else if (identityPublicKey.Equals(x5u))
                        {
                            Log.Debug("Derived Key is ok");
                        }
                        // Validate

                        var key = PublicKeyFactory.CreateKey(x5u.DecodeBase64Url());

                        CertificateData data = CryptoUtils.Decode(token.ToString(), key);
                        if (data != null)
                        {
                            identityPublicKey = data.IdentityPublicKey;

                            if (Log.IsDebugEnabled)
                            {
                                Log.Debug("Decoded token success");
                            }

                            if (CertificateData.MojangRootKey.Equals(x5u, StringComparison.InvariantCultureIgnoreCase))
                            {
                                Log.Debug("Got Mojang key. Is valid = " + data.CertificateAuthority);
                                validationKey = data.IdentityPublicKey;
                            }
                            else if (validationKey != null && validationKey.Equals(x5u, StringComparison.InvariantCultureIgnoreCase))
                            {
                                _playerInfo.CertificateData = data;
                            }
                            else
                            {
                                if (data.ExtraData == null)
                                {
                                    continue;
                                }

                                // Self signed, make sure they don't fake XUID
                                if (data.ExtraData.Xuid != null)
                                {
                                    Log.Warn("Received fake XUID from " + data.ExtraData.DisplayName);
                                    data.ExtraData.Xuid = null;
                                }

                                _playerInfo.CertificateData = data;
                            }
                        }
                        else
                        {
                            Log.Error("Not a valid Identity Public Key for decoding");
                        }
                    }
                }

                //TODO: Implement disconnect here


                _playerInfo.Username = _playerInfo.CertificateData.ExtraData.DisplayName;
                _session.Username    = _playerInfo.Username;
                string identity = _playerInfo.CertificateData.ExtraData.Identity;

                if (Log.IsDebugEnabled)
                {
                    Log.Debug($"Connecting user {_playerInfo.Username} with identity={identity}");
                }
                _playerInfo.ClientUuid = new UUID(identity);

                bool useEncryption = (Config.GetProperty("UseEncryptionForAll", false) ||
                                      (Config.GetProperty("UseEncryption", true) &&
                                       !string.IsNullOrWhiteSpace(_playerInfo.CertificateData.ExtraData.Xuid)));

                if (useEncryption)
                {
                    var publicKey = PublicKeyFactory.CreateKey(_playerInfo.CertificateData.IdentityPublicKey.DecodeBase64Url());

                    string                    namedCurve = "secp384r1";
                    ECKeyPairGenerator        pGen       = new ECKeyPairGenerator();
                    ECKeyGenerationParameters genParam   = new ECKeyGenerationParameters(
                        SecNamedCurves.GetOid(namedCurve),
                        new SecureRandom());
                    pGen.Init(genParam);

                    AsymmetricCipherKeyPair keyPair = pGen.GenerateKeyPair();

                    ECDHBasicAgreement agreement = new ECDHBasicAgreement();
                    agreement.Init(keyPair.Private);

                    byte[] preHash = agreement.CalculateAgreement(publicKey).ToByteArray();

                    byte[] prepend = Encoding.UTF8.GetBytes("RANDOM SECRET");
                    byte[] secret;

                    SHA256Managed sha = new SHA256Managed();
                    using (var memoryStream = new MemoryStream())
                    {
                        memoryStream.Write(prepend, 0, prepend.Length);
                        memoryStream.Write(preHash, 0, preHash.Length);
                        memoryStream.Position = 0;
                        secret = sha.ComputeHash(memoryStream);
                    }
                    sha.Dispose();

                    //if (Log.IsDebugEnabled) Log.Debug($"SECRET KEY (b64, {secret.Length}):\n{secret.EncodeBase64()}");

                    {
                        RijndaelManaged rijAlg = new RijndaelManaged
                        {
                            BlockSize    = 128,
                            Padding      = PaddingMode.None,
                            Mode         = CipherMode.CFB,
                            FeedbackSize = 8,
                            Key          = secret,
                            IV           = secret.Take(16).ToArray(),
                        };

                        // Create a decrytor to perform the stream transform.
                        ICryptoTransform decryptor      = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
                        MemoryStream     inputStream    = new MemoryStream();
                        CryptoStream     cryptoStreamIn = new CryptoStream(inputStream, decryptor, CryptoStreamMode.Read);

                        ICryptoTransform encryptor       = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
                        MemoryStream     outputStream    = new MemoryStream();
                        CryptoStream     cryptoStreamOut = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write);

                        _session.CryptoContext = new CryptoContext
                        {
                            UseEncryption   = true,
                            Algorithm       = rijAlg,
                            Decryptor       = decryptor,
                            Encryptor       = encryptor,
                            InputStream     = inputStream,
                            OutputStream    = outputStream,
                            CryptoStreamIn  = cryptoStreamIn,
                            CryptoStreamOut = cryptoStreamOut
                        };


                        var pubKey1 = ((ECPublicKeyParameters)keyPair.Public);

                        byte[] asn = new byte[24]
                        {
                            0x30, 0x76, 0x30, 0x10, 0x6, 0x7, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x2,
                            0x1, 0x6, 0x5, 0x2b, 0x81, 0x4, 0x0, 0x22, 0x3, 0x62, 0x0, 0x4
                        };
                        string b64Key        = asn.Concat(ConvertToNCryptEccPublicBlob(pubKey1.Q).Skip(8)).ToArray().EncodeBase64();
                        var    handshakeJson = new HandshakeData()
                        {
                            salt = prepend.EncodeBase64()
                        };

                        string val = CryptoUtils.Encode(handshakeJson, keyPair.Private, JwsAlgorithm.ES384,
                                                        new Dictionary <string, object> {
                            { "x5u", b64Key }
                        });

                        var response = McpeServerToClientHandshake.CreateObject();
                        response.NoBatch    = true;
                        response.ForceClear = true;
                        response.token      = val;

                        _session.SendPackage(response);

                        if (Log.IsDebugEnabled)
                        {
                            Log.Warn($"Encryption enabled for {_session.Username}");
                        }
                    }
                }
                else
                {
                    _session.CryptoContext = new CryptoContext
                    {
                        UseEncryption = false
                    };

                    _session.MessageHandler.HandleMcpeClientToServerHandshake(null);
                }
            }
            catch (Exception e)
            {
                Log.Error("Decrypt", e);
            }
        }
        public static AsymmetricKeyParameter CreateKey(
            PrivateKeyInfo keyInfo)
        {
            AlgorithmIdentifier algID  = keyInfo.PrivateKeyAlgorithm;
            DerObjectIdentifier algOid = algID.Algorithm;

            // TODO See RSAUtil.isRsaOid in Java build
            if (algOid.Equals(PkcsObjectIdentifiers.RsaEncryption) ||
                algOid.Equals(X509ObjectIdentifiers.IdEARsa) ||
                algOid.Equals(PkcsObjectIdentifiers.IdRsassaPss) ||
                algOid.Equals(PkcsObjectIdentifiers.IdRsaesOaep))
            {
                RsaPrivateKeyStructure keyStructure = RsaPrivateKeyStructure.GetInstance(keyInfo.ParsePrivateKey());

                return(new RsaPrivateCrtKeyParameters(
                           keyStructure.Modulus,
                           keyStructure.PublicExponent,
                           keyStructure.PrivateExponent,
                           keyStructure.Prime1,
                           keyStructure.Prime2,
                           keyStructure.Exponent1,
                           keyStructure.Exponent2,
                           keyStructure.Coefficient));
            }
            // TODO?
//			else if (algOid.Equals(X9ObjectIdentifiers.DHPublicNumber))
            else if (algOid.Equals(PkcsObjectIdentifiers.DhKeyAgreement))
            {
                DHParameter para = new DHParameter(
                    Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
                DerInteger derX = (DerInteger)keyInfo.ParsePrivateKey();

                BigInteger   lVal     = para.L;
                int          l        = lVal == null ? 0 : lVal.IntValue;
                DHParameters dhParams = new DHParameters(para.P, para.G, null, l);

                return(new DHPrivateKeyParameters(derX.Value, dhParams, algOid));
            }
            else if (algOid.Equals(OiwObjectIdentifiers.ElGamalAlgorithm))
            {
                ElGamalParameter para = new ElGamalParameter(
                    Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
                DerInteger derX = (DerInteger)keyInfo.ParsePrivateKey();

                return(new ElGamalPrivateKeyParameters(
                           derX.Value,
                           new ElGamalParameters(para.P, para.G)));
            }
            else if (algOid.Equals(X9ObjectIdentifiers.IdDsa))
            {
                DerInteger    derX = (DerInteger)keyInfo.ParsePrivateKey();
                Asn1Encodable ae   = algID.Parameters;

                DsaParameters parameters = null;
                if (ae != null)
                {
                    DsaParameter para = DsaParameter.GetInstance(ae.ToAsn1Object());
                    parameters = new DsaParameters(para.P, para.Q, para.G);
                }

                return(new DsaPrivateKeyParameters(derX.Value, parameters));
            }
            else if (algOid.Equals(X9ObjectIdentifiers.IdECPublicKey))
            {
                X962Parameters para = new X962Parameters(algID.Parameters.ToAsn1Object());

                X9ECParameters x9;
                if (para.IsNamedCurve)
                {
                    x9 = ECKeyPairGenerator.FindECCurveByOid((DerObjectIdentifier)para.Parameters);
                }
                else
                {
                    x9 = new X9ECParameters((Asn1Sequence)para.Parameters);
                }

                ECPrivateKeyStructure ec = ECPrivateKeyStructure.GetInstance(keyInfo.ParsePrivateKey());
                BigInteger            d  = ec.GetKey();

                if (para.IsNamedCurve)
                {
                    return(new ECPrivateKeyParameters("EC", d, (DerObjectIdentifier)para.Parameters));
                }

                ECDomainParameters dParams = new ECDomainParameters(x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed());
                return(new ECPrivateKeyParameters(d, dParams));
            }
            else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001))
            {
                Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters(
                    Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));

                ECDomainParameters ecP = ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet);

                if (ecP == null)
                {
                    throw new ArgumentException("Unrecognized curve OID for GostR3410x2001 private key");
                }

                Asn1Object            privKey = keyInfo.ParsePrivateKey();
                ECPrivateKeyStructure ec;

                if (privKey is DerInteger)
                {
                    ec = new ECPrivateKeyStructure(ecP.N.BitLength, ((DerInteger)privKey).PositiveValue);
                }
                else
                {
                    ec = ECPrivateKeyStructure.GetInstance(privKey);
                }

                return(new ECPrivateKeyParameters("ECGOST3410", ec.GetKey(), gostParams.PublicKeyParamSet));
            }
            else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x94))
            {
                Gost3410PublicKeyAlgParameters gostParams = Gost3410PublicKeyAlgParameters.GetInstance(algID.Parameters);

                Asn1Object privKey = keyInfo.ParsePrivateKey();
                BigInteger x;

                if (privKey is DerInteger)
                {
                    x = DerInteger.GetInstance(privKey).PositiveValue;
                }
                else
                {
                    x = new BigInteger(1, Arrays.Reverse(Asn1OctetString.GetInstance(privKey).GetOctets()));
                }

                return(new Gost3410PrivateKeyParameters(x, gostParams.PublicKeyParamSet));
            }
            else if (algOid.Equals(EdECObjectIdentifiers.id_X25519))
            {
                return(new X25519PrivateKeyParameters(GetRawKey(keyInfo, X25519PrivateKeyParameters.KeySize), 0));
            }
            else if (algOid.Equals(EdECObjectIdentifiers.id_X448))
            {
                return(new X448PrivateKeyParameters(GetRawKey(keyInfo, X448PrivateKeyParameters.KeySize), 0));
            }
            else if (algOid.Equals(EdECObjectIdentifiers.id_Ed25519))
            {
                return(new Ed25519PrivateKeyParameters(GetRawKey(keyInfo, Ed25519PrivateKeyParameters.KeySize), 0));
            }
            else if (algOid.Equals(EdECObjectIdentifiers.id_Ed448))
            {
                return(new Ed448PrivateKeyParameters(GetRawKey(keyInfo, Ed448PrivateKeyParameters.KeySize), 0));
            }
            else
            {
                throw new SecurityUtilityException("algorithm identifier in private key not recognised");
            }
        }
예제 #3
0
    private object ReadPrivateKey(PemObject pemObject)
    {
        string text = pemObject.Type.Substring(0, pemObject.Type.Length - "PRIVATE KEY".Length).Trim();

        byte[]      array      = pemObject.Content;
        IDictionary dictionary = Platform.CreateHashtable();

        foreach (PemHeader header in pemObject.Headers)
        {
            dictionary[header.Name] = header.Value;
        }
        string a = (string)dictionary["Proc-Type"];

        if (a == "4,ENCRYPTED")
        {
            if (pFinder == null)
            {
                throw new PasswordException("No password finder specified, but a password is required");
            }
            char[] password = pFinder.GetPassword();
            if (password == null)
            {
                throw new PasswordException("Password is null, but a password is required");
            }
            string   text2      = (string)dictionary["DEK-Info"];
            string[] array2     = text2.Split(',');
            string   dekAlgName = array2[0].Trim();
            byte[]   iv         = Hex.Decode(array2[1].Trim());
            array = PemUtilities.Crypt(encrypt: false, array, password, dekAlgName, iv);
        }
        try
        {
            Asn1Sequence           instance = Asn1Sequence.GetInstance(array);
            AsymmetricKeyParameter publicParameter;
            AsymmetricKeyParameter asymmetricKeyParameter;
            switch (text)
            {
            case "RSA":
            {
                if (instance.Count != 9)
                {
                    throw new PemException("malformed sequence in RSA private key");
                }
                RsaPrivateKeyStructure instance2 = RsaPrivateKeyStructure.GetInstance(instance);
                publicParameter        = new RsaKeyParameters(isPrivate: false, instance2.Modulus, instance2.PublicExponent);
                asymmetricKeyParameter = new RsaPrivateCrtKeyParameters(instance2.Modulus, instance2.PublicExponent, instance2.PrivateExponent, instance2.Prime1, instance2.Prime2, instance2.Exponent1, instance2.Exponent2, instance2.Coefficient);
                break;
            }

            case "DSA":
            {
                if (instance.Count != 6)
                {
                    throw new PemException("malformed sequence in DSA private key");
                }
                DerInteger    derInteger  = (DerInteger)instance[1];
                DerInteger    derInteger2 = (DerInteger)instance[2];
                DerInteger    derInteger3 = (DerInteger)instance[3];
                DerInteger    derInteger4 = (DerInteger)instance[4];
                DerInteger    derInteger5 = (DerInteger)instance[5];
                DsaParameters parameters  = new DsaParameters(derInteger.Value, derInteger2.Value, derInteger3.Value);
                asymmetricKeyParameter = new DsaPrivateKeyParameters(derInteger5.Value, parameters);
                publicParameter        = new DsaPublicKeyParameters(derInteger4.Value, parameters);
                break;
            }

            case "EC":
            {
                ECPrivateKeyStructure instance3 = ECPrivateKeyStructure.GetInstance(instance);
                AlgorithmIdentifier   algID     = new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, instance3.GetParameters());
                PrivateKeyInfo        keyInfo   = new PrivateKeyInfo(algID, instance3.ToAsn1Object());
                asymmetricKeyParameter = PrivateKeyFactory.CreateKey(keyInfo);
                DerBitString publicKey = instance3.GetPublicKey();
                if (publicKey != null)
                {
                    SubjectPublicKeyInfo keyInfo2 = new SubjectPublicKeyInfo(algID, publicKey.GetBytes());
                    publicParameter = PublicKeyFactory.CreateKey(keyInfo2);
                }
                else
                {
                    publicParameter = ECKeyPairGenerator.GetCorrespondingPublicKey((ECPrivateKeyParameters)asymmetricKeyParameter);
                }
                break;
            }

            case "ENCRYPTED":
            {
                char[] password2 = pFinder.GetPassword();
                if (password2 == null)
                {
                    throw new PasswordException("Password is null, but a password is required");
                }
                return(PrivateKeyFactory.DecryptKey(password2, EncryptedPrivateKeyInfo.GetInstance(instance)));
            }

            case "":
                return(PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(instance)));

            default:
                throw new ArgumentException("Unknown key type: " + text, "type");
            }
            return(new AsymmetricCipherKeyPair(publicParameter, asymmetricKeyParameter));
        }
        catch (IOException ex)
        {
            throw ex;
        }
        catch (Exception ex2)
        {
            throw new PemException("problem creating " + text + " private key: " + ex2.ToString());
        }
    }
예제 #4
0
        private static AsymmetricCipherKeyPair GenerateKeys(X509V3CertificateGenerator certificateGenerator, SecureRandom random,
                                                            SignatureHashAlgorithm signatureAlgorithm)
        {
            if (certificateGenerator == null)
            {
                throw new ArgumentNullException(nameof(certificateGenerator));
            }

            if (random == null)
            {
                throw new ArgumentNullException(nameof(random));
            }

            if (signatureAlgorithm == null)
            {
                throw new ArgumentNullException(nameof(signatureAlgorithm));
            }

            AsymmetricCipherKeyPair result = null;

            switch (signatureAlgorithm.Signature)
            {
            case TSignatureAlgorithm.Anonymous:
            {
                break;
            }

            case TSignatureAlgorithm.RSA:
            {
                var keyGenerationParameters = new KeyGenerationParameters(random, 2048);
                var rsaKeyPairGenerator     = new RsaKeyPairGenerator();
                rsaKeyPairGenerator.Init(keyGenerationParameters);
                result = rsaKeyPairGenerator.GenerateKeyPair();
                break;
            }

            case TSignatureAlgorithm.DSA:
            {
                break;
            }

            case TSignatureAlgorithm.ECDSA:
            {
                //ECDomainParameters ellipticCurveParameters = EllipticCurveFactory.GetEllipticCurveParameters(TEllipticCurve.secp256r1);
                var keyPairGenerator = new ECKeyPairGenerator();
                //keyPairGenerator.Init(new ECKeyGenerationParameters(ellipticCurveParameters, random));
                keyPairGenerator.Init(new ECKeyGenerationParameters(SecObjectIdentifiers.SecP256r1, random));
                result = keyPairGenerator.GenerateKeyPair();
                //certificateGenerator.AddExtension(X509Extensions.SubjectPublicKeyInfo)
                //PrivateKey = (ECPrivateKeyParameters)keys.Private;
                //PublicKey = (ECPublicKeyParameters)keys.Public;
                break;
            }

            default:
            {
                break;
            }
            }

            certificateGenerator.SetPublicKey(result.Public);
            return(result);
        }
        internal void MakeCertChain(DeviceBundle bundle, int chainLen, int fwidSeed)
        {
            var aliasCert = bundle.AliasCert;

            DateTime now = DateTime.Now;

            byte[] fwid = Helpers.HashData(new byte[1] {
                0
            }, 0, 1);
            const int keyStrength           = 256;
            CryptoApiRandomGenerator rg     = new CryptoApiRandomGenerator();
            SecureRandom             random = new SecureRandom(rg);
            KeyGenerationParameters  keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
            var keyPairGenerator = new ECKeyPairGenerator();

            keyPairGenerator.Init(keyGenerationParameters);

            // Starting the loop we have a (not yet certified) DeviceID public key
            // and the Issuer of the Alias Cert (which we want to be the DevID-cert DN.)

            List <X509Certificate> certChain = new List <X509Certificate>();

            var lastCertIssuer = aliasCert.IssuerDN;
            var lastPubKey     = bundle.DeviceIDPublic;;
            AsymmetricCipherKeyPair lastKeyPair = null;

            for (int j = 0; j < chainLen; j++)
            {
                bool rootCert   = j == chainLen - 1;
                bool lastButOne = j == chainLen - 2;
                AsymmetricCipherKeyPair caKey = keyPairGenerator.GenerateKeyPair();

                X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
                certGen.SetSerialNumber(new BigInteger(new byte[] { 1, 2, 3, 4, 5 }));
                var issuerDn = lastButOne ?
                               new X509Name($"CN=Vendor Root CA O=MSR_TEST, C=US") :
                               new X509Name($"CN=Vendor Intermediate CA {j}, O=MSR_TEST, C=US");
                if (rootCert)
                {
                    issuerDn = lastCertIssuer;
                }

                certGen.SetIssuerDN(issuerDn);
                certGen.SetSubjectDN(lastCertIssuer);
                certGen.SetNotBefore(now);
                certGen.SetNotAfter(now + new TimeSpan(365 * 10, 0, 0, 0, 0));
                certGen.SetPublicKey(lastPubKey);



                int pathLengthConstraint = j + 1;
                certGen.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(pathLengthConstraint));
                certGen.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.KeyCertSign));
                X509Certificate certificate;

                if (rootCert)
                {
                    ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WITHECDSA", lastKeyPair.Private, random);
                    certificate = certGen.Generate(signatureFactory);
                }
                else
                {
                    ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WITHECDSA", caKey.Private, random);
                    certificate = certGen.Generate(signatureFactory);
                }


                lastCertIssuer = certificate.IssuerDN;
                lastPubKey     = caKey.Public;
                lastKeyPair    = caKey;
                certChain.Add(certificate);
            }


            // Chain including root, but not AliasCert.  NOTE, finishes with CA
            Helpers.WritePEMObjects(ToPath(Program.DeviceCertChain), certChain.ToArray());
            // cert chain including AliasCert (alias cert is first.  CA is last)
            JoinFiles(Program.AliasCert, Program.DeviceCertChain, Program.DeviceCertChainIncAlias);

            // just the device CA (for the server)
            Helpers.WritePEMObject(ToPath("DeviceCA.pem"), certChain.Last());


            // Now make some certs for the server to use
            string serverCaName = "CN=Server CA, C=US, O=MSR_TEST";
            string serverName   = "CN=Server Cert, C=US, O=MSR_TEST";

            var serverCA   = MakeCertInternal(serverCaName, serverCaName, true, null, null, 1);
            var serverCert = MakeCertInternal(serverCaName, serverName, false, serverCA.KeyPair, null, 0);

            Helpers.WritePEMObject(ToPath(Program.ServerCA), serverCA.Certificate);
            Helpers.WritePEMObjects(ToPath(Program.ServerChain), new Object[] { serverCA.Certificate, serverCert.Certificate });
            //Helpers.WritePEMObject(ToPath("T0_ServerCAKey.PEM", serverCA.KeyPair);
            Helpers.WritePEMObject(ToPath(Program.ServerCert), serverCert.Certificate);
            Helpers.WritePEMObject(ToPath(Program.ServerKey), serverCert.KeyPair);

            // OpenSSL needs a file with the Device CA AND the server CA
            JoinFiles(Program.DeviceCertChain, Program.ServerCA, Program.DeviceCertChainAndServerCA);

            // OpenSSL test scripts -

            // print a cert
            // openssl x509 -text -in T0_ServerCA.pem

            // Just verify the client chain
            // openssl verify -purpose sslclient -CAfile T0_DeviceCertChain.PEM DeviceAliasCert.PEM

            // Just verify the server chain
            // openssl verify -purpose sslserver -CAfile T0_ServerCA.PEM T0_ServerCert.PEM


            // openssl s_client -connect localhost: 5556 - cert T0_AliasCert.PEM - key T0_AliasKey.PEM - CAfile T0_DeviceCertChainAndServerCA.PEM
            // openssl s_client -connect localhost:5556 -cert T0_AliasCert.PEM -key T0_AliasKey.PEM -CAfile T0_DeviceCertChain.PEM
            // openssl s_server -cert T0_ServerCert.PEM -key T0_ServerKey.PEM -CAfile T0_DeviceCertChainAndServerCA.PEM -status_verbose -verify 10 -rev -accept 5556

            return;
        }
예제 #6
0
        private byte[] RecoverSessionData(PgpPrivateKey privKey)
        {
            byte[][] secKeyData = keyData.GetEncSessionKey();

            if (keyData.Algorithm == PublicKeyAlgorithmTag.ECDH)
            {
                ECDHPublicBcpgKey ecKey    = (ECDHPublicBcpgKey)privKey.PublicKeyPacket.Key;
                X9ECParameters    x9Params = ECKeyPairGenerator.FindECCurveByOid(ecKey.CurveOid);

                byte[] enc = secKeyData[0];

                int    pLen = ((((enc[0] & 0xff) << 8) + (enc[1] & 0xff)) + 7) / 8;
                byte[] pEnc = new byte[pLen];

                Array.Copy(enc, 2, pEnc, 0, pLen);

                byte[] keyEnc = new byte[enc[pLen + 2]];

                Array.Copy(enc, 2 + pLen + 1, keyEnc, 0, keyEnc.Length);

                ECPoint publicPoint = x9Params.Curve.DecodePoint(pEnc);

                ECPrivateKeyParameters privKeyParams = (ECPrivateKeyParameters)privKey.Key;
                ECPoint S = publicPoint.Multiply(privKeyParams.D).Normalize();

                KeyParameter key = new KeyParameter(Rfc6637Utilities.CreateKey(privKey.PublicKeyPacket, S));

                IWrapper w = PgpUtilities.CreateWrapper(ecKey.SymmetricKeyAlgorithm);
                w.Init(false, key);

                return(PgpPad.UnpadSessionData(w.Unwrap(keyEnc, 0, keyEnc.Length)));
            }

            IBufferedCipher cipher = GetKeyCipher(keyData.Algorithm);

            try
            {
                cipher.Init(false, privKey.Key);
            }
            catch (InvalidKeyException e)
            {
                throw new PgpException("error setting asymmetric cipher", e);
            }

            if (keyData.Algorithm == PublicKeyAlgorithmTag.RsaEncrypt ||
                keyData.Algorithm == PublicKeyAlgorithmTag.RsaGeneral)
            {
                byte[] bi = secKeyData[0];

                cipher.ProcessBytes(bi, 2, bi.Length - 2);
            }
            else
            {
                ElGamalPrivateKeyParameters k = (ElGamalPrivateKeyParameters)privKey.Key;
                int size = (k.Parameters.P.BitLength + 7) / 8;

                ProcessEncodedMpi(cipher, size, secKeyData[0]);
                ProcessEncodedMpi(cipher, size, secKeyData[1]);
            }

            try
            {
                return(cipher.DoFinal());
            }
            catch (Exception e)
            {
                throw new PgpException("exception decrypting secret key", e);
            }
        }
예제 #7
0
        public static AsymmetricKeyParameter CreateKey(
            SubjectPublicKeyInfo keyInfo)
        {
            AlgorithmIdentifier algID  = keyInfo.AlgorithmID;
            DerObjectIdentifier algOid = algID.ObjectID;

            // TODO See RSAUtil.isRsaOid in Java build
            if (algOid.Equals(PkcsObjectIdentifiers.RsaEncryption) ||
                algOid.Equals(X509ObjectIdentifiers.IdEARsa) ||
                algOid.Equals(PkcsObjectIdentifiers.IdRsassaPss) ||
                algOid.Equals(PkcsObjectIdentifiers.IdRsaesOaep))
            {
                RsaPublicKeyStructure pubKey = RsaPublicKeyStructure.GetInstance(
                    keyInfo.GetPublicKey());

                return(new RsaKeyParameters(false, pubKey.Modulus, pubKey.PublicExponent));
            }
            else if (algOid.Equals(X9ObjectIdentifiers.DHPublicNumber))
            {
                Asn1Sequence seq = Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object());

                DHPublicKey dhPublicKey = DHPublicKey.GetInstance(keyInfo.GetPublicKey());

                BigInteger y = dhPublicKey.Y.Value;

                if (IsPkcsDHParam(seq))
                {
                    return(ReadPkcsDHParam(algOid, y, seq));
                }

                DHDomainParameters dhParams = DHDomainParameters.GetInstance(seq);

                BigInteger p = dhParams.P.Value;
                BigInteger g = dhParams.G.Value;
                BigInteger q = dhParams.Q.Value;

                BigInteger j = null;
                if (dhParams.J != null)
                {
                    j = dhParams.J.Value;
                }

                DHValidationParameters validation        = null;
                DHValidationParms      dhValidationParms = dhParams.ValidationParms;
                if (dhValidationParms != null)
                {
                    byte[]     seed        = dhValidationParms.Seed.GetBytes();
                    BigInteger pgenCounter = dhValidationParms.PgenCounter.Value;

                    // TODO Check pgenCounter size?

                    validation = new DHValidationParameters(seed, pgenCounter.IntValue);
                }

                return(new DHPublicKeyParameters(y, new DHParameters(p, g, q, j, validation)));
            }
            else if (algOid.Equals(PkcsObjectIdentifiers.DhKeyAgreement))
            {
                Asn1Sequence seq = Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object());

                DerInteger derY = (DerInteger)keyInfo.GetPublicKey();

                return(ReadPkcsDHParam(algOid, derY.Value, seq));
            }
            else if (algOid.Equals(OiwObjectIdentifiers.ElGamalAlgorithm))
            {
                ElGamalParameter para = new ElGamalParameter(
                    Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
                DerInteger derY = (DerInteger)keyInfo.GetPublicKey();

                return(new ElGamalPublicKeyParameters(
                           derY.Value,
                           new ElGamalParameters(para.P, para.G)));
            }
            else if (algOid.Equals(X9ObjectIdentifiers.IdDsa) ||
                     algOid.Equals(OiwObjectIdentifiers.DsaWithSha1))
            {
                DerInteger    derY = (DerInteger)keyInfo.GetPublicKey();
                Asn1Encodable ae   = algID.Parameters;

                DsaParameters parameters = null;
                if (ae != null)
                {
                    DsaParameter para = DsaParameter.GetInstance(ae.ToAsn1Object());
                    parameters = new DsaParameters(para.P, para.Q, para.G);
                }

                return(new DsaPublicKeyParameters(derY.Value, parameters));
            }
            else if (algOid.Equals(X9ObjectIdentifiers.IdECPublicKey))
            {
                X962Parameters para = new X962Parameters(
                    algID.Parameters.ToAsn1Object());
                X9ECParameters ecP;

                if (para.IsNamedCurve)
                {
                    ecP = ECKeyPairGenerator.FindECCurveByOid((DerObjectIdentifier)para.Parameters);
                }
                else
                {
                    ecP = new X9ECParameters((Asn1Sequence)para.Parameters);
                }

                ECDomainParameters dParams = new ECDomainParameters(
                    ecP.Curve,
                    ecP.G,
                    ecP.N,
                    ecP.H,
                    ecP.GetSeed());

                DerBitString    bits = keyInfo.PublicKeyData;
                byte[]          data = bits.GetBytes();
                Asn1OctetString key  = new DerOctetString(data);

                X9ECPoint derQ = new X9ECPoint(dParams.Curve, key);

                return(new ECPublicKeyParameters(derQ.Point, dParams));
            }
            else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001))
            {
                Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters(
                    (Asn1Sequence)algID.Parameters);

                Asn1OctetString key;
                try
                {
                    key = (Asn1OctetString)keyInfo.GetPublicKey();
                }
                catch (IOException)
                {
                    throw new ArgumentException("invalid info structure in GOST3410 public key");
                }

                byte[] keyEnc = key.GetOctets();
                byte[] x      = new byte[32];
                byte[] y      = new byte[32];

                for (int i = 0; i != y.Length; i++)
                {
                    x[i] = keyEnc[32 - 1 - i];
                }

                for (int i = 0; i != x.Length; i++)
                {
                    y[i] = keyEnc[64 - 1 - i];
                }

                ECDomainParameters ecP = ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet);

                if (ecP == null)
                {
                    return(null);
                }

                ECPoint q = ecP.Curve.CreatePoint(new BigInteger(1, x), new BigInteger(1, y), false);

                return(new ECPublicKeyParameters("ECGOST3410", q, gostParams.PublicKeyParamSet));
            }
            else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x94))
            {
                Gost3410PublicKeyAlgParameters algParams = new Gost3410PublicKeyAlgParameters(
                    (Asn1Sequence)algID.Parameters);

                DerOctetString derY;
                try
                {
                    derY = (DerOctetString)keyInfo.GetPublicKey();
                }
                catch (IOException)
                {
                    throw new ArgumentException("invalid info structure in GOST3410 public key");
                }

                byte[] keyEnc   = derY.GetOctets();
                byte[] keyBytes = new byte[keyEnc.Length];

                for (int i = 0; i != keyEnc.Length; i++)
                {
                    keyBytes[i] = keyEnc[keyEnc.Length - 1 - i];                     // was little endian
                }

                BigInteger y = new BigInteger(1, keyBytes);

                return(new Gost3410PublicKeyParameters(y, algParams.PublicKeyParamSet));
            }
            else
            {
                throw new SecurityUtilityException("algorithm identifier in key not recognised: " + algOid);
            }
        }
예제 #8
0
        public static AsymmetricKeyParameter CreateKey(PrivateKeyInfo keyInfo)
        {
            //IL_02a2: Unknown result type (might be due to invalid IL or missing references)
            AlgorithmIdentifier privateKeyAlgorithm = keyInfo.PrivateKeyAlgorithm;
            DerObjectIdentifier algorithm           = privateKeyAlgorithm.Algorithm;

            if (algorithm.Equals(PkcsObjectIdentifiers.RsaEncryption) || algorithm.Equals(X509ObjectIdentifiers.IdEARsa) || algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss) || algorithm.Equals(PkcsObjectIdentifiers.IdRsaesOaep))
            {
                RsaPrivateKeyStructure instance = RsaPrivateKeyStructure.GetInstance(keyInfo.ParsePrivateKey());
                return(new RsaPrivateCrtKeyParameters(instance.Modulus, instance.PublicExponent, instance.PrivateExponent, instance.Prime1, instance.Prime2, instance.Exponent1, instance.Exponent2, instance.Coefficient));
            }
            if (algorithm.Equals(PkcsObjectIdentifiers.DhKeyAgreement))
            {
                DHParameter  dHParameter = new DHParameter(Asn1Sequence.GetInstance(privateKeyAlgorithm.Parameters.ToAsn1Object()));
                DerInteger   derInteger  = (DerInteger)keyInfo.ParsePrivateKey();
                int          l           = dHParameter.L?.IntValue ?? 0;
                DHParameters parameters  = new DHParameters(dHParameter.P, dHParameter.G, null, l);
                return(new DHPrivateKeyParameters(derInteger.Value, parameters, algorithm));
            }
            if (algorithm.Equals(OiwObjectIdentifiers.ElGamalAlgorithm))
            {
                ElGamalParameter elGamalParameter = new ElGamalParameter(Asn1Sequence.GetInstance(privateKeyAlgorithm.Parameters.ToAsn1Object()));
                DerInteger       derInteger2      = (DerInteger)keyInfo.ParsePrivateKey();
                return(new ElGamalPrivateKeyParameters(derInteger2.Value, new ElGamalParameters(elGamalParameter.P, elGamalParameter.G)));
            }
            if (algorithm.Equals(X9ObjectIdentifiers.IdDsa))
            {
                DerInteger    derInteger3 = (DerInteger)keyInfo.ParsePrivateKey();
                Asn1Encodable parameters2 = privateKeyAlgorithm.Parameters;
                DsaParameters parameters3 = null;
                if (parameters2 != null)
                {
                    DsaParameter instance2 = DsaParameter.GetInstance(parameters2.ToAsn1Object());
                    parameters3 = new DsaParameters(instance2.P, instance2.Q, instance2.G);
                }
                return(new DsaPrivateKeyParameters(derInteger3.Value, parameters3));
            }
            if (algorithm.Equals(X9ObjectIdentifiers.IdECPublicKey))
            {
                X962Parameters        x962Parameters = new X962Parameters(privateKeyAlgorithm.Parameters.ToAsn1Object());
                X9ECParameters        x9ECParameters = ((!x962Parameters.IsNamedCurve) ? new X9ECParameters((Asn1Sequence)x962Parameters.Parameters) : ECKeyPairGenerator.FindECCurveByOid((DerObjectIdentifier)x962Parameters.Parameters));
                ECPrivateKeyStructure instance3      = ECPrivateKeyStructure.GetInstance(keyInfo.ParsePrivateKey());
                BigInteger            key            = instance3.GetKey();
                if (x962Parameters.IsNamedCurve)
                {
                    return(new ECPrivateKeyParameters("EC", key, (DerObjectIdentifier)x962Parameters.Parameters));
                }
                ECDomainParameters parameters4 = new ECDomainParameters(x9ECParameters.Curve, x9ECParameters.G, x9ECParameters.N, x9ECParameters.H, x9ECParameters.GetSeed());
                return(new ECPrivateKeyParameters(key, parameters4));
            }
            if (algorithm.Equals(CryptoProObjectIdentifiers.GostR3410x2001))
            {
                Gost3410PublicKeyAlgParameters gost3410PublicKeyAlgParameters = new Gost3410PublicKeyAlgParameters(Asn1Sequence.GetInstance(privateKeyAlgorithm.Parameters.ToAsn1Object()));
                ECDomainParameters             byOid = ECGost3410NamedCurves.GetByOid(gost3410PublicKeyAlgParameters.PublicKeyParamSet);
                if (byOid == null)
                {
                    throw new ArgumentException("Unrecognized curve OID for GostR3410x2001 private key");
                }
                Asn1Object            asn1Object            = keyInfo.ParsePrivateKey();
                ECPrivateKeyStructure eCPrivateKeyStructure = ((!(asn1Object is DerInteger)) ? ECPrivateKeyStructure.GetInstance(asn1Object) : new ECPrivateKeyStructure(byOid.N.BitLength, ((DerInteger)asn1Object).Value));
                return(new ECPrivateKeyParameters("ECGOST3410", eCPrivateKeyStructure.GetKey(), gost3410PublicKeyAlgParameters.PublicKeyParamSet));
            }
            if (algorithm.Equals(CryptoProObjectIdentifiers.GostR3410x94))
            {
                Gost3410PublicKeyAlgParameters gost3410PublicKeyAlgParameters2 = new Gost3410PublicKeyAlgParameters(Asn1Sequence.GetInstance(privateKeyAlgorithm.Parameters.ToAsn1Object()));
                DerOctetString derOctetString = (DerOctetString)keyInfo.ParsePrivateKey();
                BigInteger     x = new BigInteger(1, Arrays.Reverse(derOctetString.GetOctets()));
                return(new Gost3410PrivateKeyParameters(x, gost3410PublicKeyAlgParameters2.PublicKeyParamSet));
            }
            throw new SecurityUtilityException("algorithm identifier in key not recognised");
        }
예제 #9
0
        public static AsymmetricKeyParameter CreateKey(SubjectPublicKeyInfo keyInfo)
        {
            AlgorithmIdentifier algorithmID = keyInfo.AlgorithmID;
            DerObjectIdentifier objectID    = algorithmID.ObjectID;

            if (objectID.Equals(PkcsObjectIdentifiers.RsaEncryption) || objectID.Equals(X509ObjectIdentifiers.IdEARsa) || objectID.Equals(PkcsObjectIdentifiers.IdRsassaPss) || objectID.Equals(PkcsObjectIdentifiers.IdRsaesOaep))
            {
                RsaPublicKeyStructure instance = RsaPublicKeyStructure.GetInstance(keyInfo.GetPublicKey());
                return(new RsaKeyParameters(isPrivate: false, instance.Modulus, instance.PublicExponent));
            }
            if (objectID.Equals(X9ObjectIdentifiers.DHPublicNumber))
            {
                Asn1Sequence instance2 = Asn1Sequence.GetInstance(algorithmID.Parameters.ToAsn1Object());
                DHPublicKey  instance3 = DHPublicKey.GetInstance(keyInfo.GetPublicKey());
                BigInteger   value     = instance3.Y.Value;
                if (IsPkcsDHParam(instance2))
                {
                    return(ReadPkcsDHParam(objectID, value, instance2));
                }
                DHDomainParameters instance4 = DHDomainParameters.GetInstance(instance2);
                BigInteger         value2    = instance4.P.Value;
                BigInteger         value3    = instance4.G.Value;
                BigInteger         value4    = instance4.Q.Value;
                BigInteger         j         = null;
                if (instance4.J != null)
                {
                    j = instance4.J.Value;
                }
                DHValidationParameters validation      = null;
                DHValidationParms      validationParms = instance4.ValidationParms;
                if (validationParms != null)
                {
                    byte[]     bytes  = validationParms.Seed.GetBytes();
                    BigInteger value5 = validationParms.PgenCounter.Value;
                    validation = new DHValidationParameters(bytes, value5.IntValue);
                }
                return(new DHPublicKeyParameters(value, new DHParameters(value2, value3, value4, j, validation)));
            }
            if (objectID.Equals(PkcsObjectIdentifiers.DhKeyAgreement))
            {
                Asn1Sequence instance5  = Asn1Sequence.GetInstance(algorithmID.Parameters.ToAsn1Object());
                DerInteger   derInteger = (DerInteger)keyInfo.GetPublicKey();
                return(ReadPkcsDHParam(objectID, derInteger.Value, instance5));
            }
            if (objectID.Equals(OiwObjectIdentifiers.ElGamalAlgorithm))
            {
                ElGamalParameter elGamalParameter = new ElGamalParameter(Asn1Sequence.GetInstance(algorithmID.Parameters.ToAsn1Object()));
                DerInteger       derInteger2      = (DerInteger)keyInfo.GetPublicKey();
                return(new ElGamalPublicKeyParameters(derInteger2.Value, new ElGamalParameters(elGamalParameter.P, elGamalParameter.G)));
            }
            if (objectID.Equals(X9ObjectIdentifiers.IdDsa) || objectID.Equals(OiwObjectIdentifiers.DsaWithSha1))
            {
                DerInteger    derInteger3 = (DerInteger)keyInfo.GetPublicKey();
                Asn1Encodable parameters  = algorithmID.Parameters;
                DsaParameters parameters2 = null;
                if (parameters != null)
                {
                    DsaParameter instance6 = DsaParameter.GetInstance(parameters.ToAsn1Object());
                    parameters2 = new DsaParameters(instance6.P, instance6.Q, instance6.G);
                }
                return(new DsaPublicKeyParameters(derInteger3.Value, parameters2));
            }
            if (objectID.Equals(X9ObjectIdentifiers.IdECPublicKey))
            {
                X962Parameters  x962Parameters = new X962Parameters(algorithmID.Parameters.ToAsn1Object());
                X9ECParameters  x9ECParameters = (!x962Parameters.IsNamedCurve) ? new X9ECParameters((Asn1Sequence)x962Parameters.Parameters) : ECKeyPairGenerator.FindECCurveByOid((DerObjectIdentifier)x962Parameters.Parameters);
                Asn1OctetString s         = new DerOctetString(keyInfo.PublicKeyData.GetBytes());
                X9ECPoint       x9ECPoint = new X9ECPoint(x9ECParameters.Curve, s);
                ECPoint         point     = x9ECPoint.Point;
                if (x962Parameters.IsNamedCurve)
                {
                    return(new ECPublicKeyParameters("EC", point, (DerObjectIdentifier)x962Parameters.Parameters));
                }
                ECDomainParameters parameters3 = new ECDomainParameters(x9ECParameters.Curve, x9ECParameters.G, x9ECParameters.N, x9ECParameters.H, x9ECParameters.GetSeed());
                return(new ECPublicKeyParameters(point, parameters3));
            }
            if (objectID.Equals(CryptoProObjectIdentifiers.GostR3410x2001))
            {
                Gost3410PublicKeyAlgParameters gost3410PublicKeyAlgParameters = new Gost3410PublicKeyAlgParameters((Asn1Sequence)algorithmID.Parameters);
                Asn1OctetString asn1OctetString;
                try
                {
                    asn1OctetString = (Asn1OctetString)keyInfo.GetPublicKey();
                }
                catch (IOException)
                {
                    throw new ArgumentException("invalid info structure in GOST3410 public key");
                    IL_038b :;
                }
                byte[] octets = asn1OctetString.GetOctets();
                byte[] array  = new byte[32];
                byte[] array2 = new byte[32];
                for (int i = 0; i != array2.Length; i++)
                {
                    array[i] = octets[31 - i];
                }
                for (int k = 0; k != array.Length; k++)
                {
                    array2[k] = octets[63 - k];
                }
                ECDomainParameters byOid = ECGost3410NamedCurves.GetByOid(gost3410PublicKeyAlgParameters.PublicKeyParamSet);
                if (byOid == null)
                {
                    return(null);
                }
                ECPoint q = byOid.Curve.CreatePoint(new BigInteger(1, array), new BigInteger(1, array2));
                return(new ECPublicKeyParameters("ECGOST3410", q, gost3410PublicKeyAlgParameters.PublicKeyParamSet));
            }
            if (objectID.Equals(CryptoProObjectIdentifiers.GostR3410x94))
            {
                Gost3410PublicKeyAlgParameters gost3410PublicKeyAlgParameters2 = new Gost3410PublicKeyAlgParameters((Asn1Sequence)algorithmID.Parameters);
                DerOctetString derOctetString;
                try
                {
                    derOctetString = (DerOctetString)keyInfo.GetPublicKey();
                }
                catch (IOException)
                {
                    throw new ArgumentException("invalid info structure in GOST3410 public key");
                    IL_0480 :;
                }
                byte[] octets2 = derOctetString.GetOctets();
                byte[] array3  = new byte[octets2.Length];
                for (int l = 0; l != octets2.Length; l++)
                {
                    array3[l] = octets2[octets2.Length - 1 - l];
                }
                BigInteger y = new BigInteger(1, array3);
                return(new Gost3410PublicKeyParameters(y, gost3410PublicKeyAlgParameters2.PublicKeyParamSet));
            }
            throw new SecurityUtilityException("algorithm identifier in key not recognised: " + objectID);
        }
예제 #10
0
        public void TestMethod1()
        {
            // this snippet can be easily used in any normal c# project as well by simply removing the .Dump() methods
            // and saving the output into a variable / file of your choice.
            // you'll need to add BouncyCastle.Crypto nuget to use this.
            // tested on 1.8.0-beta4

            AsymmetricCipherKeyPair    pair;
            Pkcs10CertificationRequest csr;

            var ecMode = false;
            var values = new Dictionary <DerObjectIdentifier, string> {
                { X509Name.CN, "" }, //domain name
                { X509Name.OU, "Domain Control Validated" },
                { X509Name.O, "" },  //Organisation's Legal name
                { X509Name.L, "London" },
                { X509Name.ST, "England" },
                { X509Name.C, "GB" },
            };

            var subjectAlternateNames = new GeneralName[] { };

            var extensions = new Dictionary <DerObjectIdentifier, X509Extension>()
            {
                { X509Extensions.BasicConstraints, new X509Extension(true, new DerOctetString(new BasicConstraints(false))) },
                { X509Extensions.KeyUsage, new X509Extension(true, new DerOctetString(new KeyUsage(KeyUsage.DigitalSignature | KeyUsage.KeyEncipherment | KeyUsage.DataEncipherment | KeyUsage.NonRepudiation))) },
                { X509Extensions.ExtendedKeyUsage, new X509Extension(false, new DerOctetString(new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth))) },
            };

            if (values[X509Name.CN].StartsWith("www."))
            {
                values[X509Name.CN] = values[X509Name.CN].Substring(4);
            }

            if (!values[X509Name.CN].StartsWith("*.") && subjectAlternateNames.Length == 0)
            {
                subjectAlternateNames = new GeneralName[] { new GeneralName(GeneralName.DnsName, $"www.{values[X509Name.CN]}") }
            }
            ;

            if (subjectAlternateNames.Length > 0)
            {
                extensions.Add(X509Extensions.SubjectAlternativeName, new X509Extension(false, new DerOctetString(new GeneralNames(subjectAlternateNames))));
            }

            var subject = new X509Name(values.Keys.Reverse().ToList(), values);

            if (ecMode)
            {
                var gen = new ECKeyPairGenerator();
                var ecp = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp384r1");
                gen.Init(new ECKeyGenerationParameters(new ECDomainParameters(ecp.Curve, ecp.G, ecp.N, ecp.H, ecp.GetSeed()), new SecureRandom()));

                pair = gen.GenerateKeyPair();

                extensions.Add(X509Extensions.SubjectKeyIdentifier, new X509Extension(false, new DerOctetString(new SubjectKeyIdentifierStructure(pair.Public))));
                csr = new Pkcs10CertificationRequest("SHA256withECDSA", subject, pair.Public, new DerSet(new AttributePkcs(PkcsObjectIdentifiers.Pkcs9AtExtensionRequest, new DerSet(new X509Extensions(extensions)))), pair.Private);
            }
            else
            {
                var gen = new RsaKeyPairGenerator();
                gen.Init(new KeyGenerationParameters(new SecureRandom(), 2048));

                pair = gen.GenerateKeyPair();
                extensions.Add(X509Extensions.SubjectKeyIdentifier, new X509Extension(false, new DerOctetString(new SubjectKeyIdentifierStructure(pair.Public))));
                csr = new Pkcs10CertificationRequest("SHA256withRSA", subject, pair.Public, new DerSet(new AttributePkcs(PkcsObjectIdentifiers.Pkcs9AtExtensionRequest, new DerSet(new X509Extensions(extensions)))), pair.Private);
            }

            //Convert BouncyCastle csr to .PEM file.
            var csrPem       = new StringBuilder();
            var csrPemWriter = new PemWriter(new StringWriter(csrPem));

            csrPemWriter.WriteObject(csr);
            csrPemWriter.Writer.Flush();

            Console.WriteLine(csrPem.ToString());

            var privateKeyPem       = new StringBuilder();
            var privateKeyPemWriter = new PemWriter(new StringWriter(privateKeyPem));

            privateKeyPemWriter.WriteObject(pair.Private);
            csrPemWriter.Writer.Flush();

            //privateKeyPem.ToString().Dump("Private Key");
        }
    }
예제 #11
0
        /// <summary>
        /// Connects to the specified device and completes encryption handshake/key generation.
        /// </summary>
        /// <param name="deviceName">Name of the device to connect to.</param>
        public async Task <bool> ConnectToDevice(string deviceName)  //, Func<bool> DisconnectedHanlder
        {
            //adapter.DeviceConnectionLost += (s, a) =>
            //{
            //    DisconnectedHanlder();
            //};

            try
            {
                IDevice device = null;
                foreach (IDevice i in deviceList)
                {
                    if (i.Name == deviceName)
                    {
                        device = i;
                        break;
                    }
                }
                await adapter.ConnectToDeviceAsync(device);

                OnPropertyChanged("BluetoothState");
                PairedDevice = device;
                var service = await device.GetServiceAsync(Guid.Parse("913CF3FD-7173-43A5-82F4-DFD6F61BAF5F"));

                characteristic = await service.GetCharacteristicAsync(Guid.Parse("44B1DF4E-15C8-4F97-9F34-123D33B0C29D"));

                X9ECParameters     x9        = ECNamedCurveTable.GetByName("secp256r1");
                ECCurve            curve     = x9.Curve;
                ECDomainParameters ecDomain  = new ECDomainParameters(x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed());
                ECKeyPairGenerator generator = (ECKeyPairGenerator)GeneratorUtilities.GetKeyPairGenerator("ECDH");
                generator.Init(new ECKeyGenerationParameters(ecDomain, new SecureRandom()));
                AsymmetricCipherKeyPair appKeyPair    = generator.GenerateKeyPair();
                ECPublicKeyParameters   appPublicKey  = (ECPublicKeyParameters)appKeyPair.Public;
                ECPrivateKeyParameters  appPrivateKey = (ECPrivateKeyParameters)appKeyPair.Private;


                // Wait for Arduino Public Key
                characteristic.ValueUpdated += GetPubKeyPortion;
                await characteristic.StartUpdatesAsync();

                Task.Run(CheckIfKeyObtainComplete).Wait();

                // Once full Key has been obtained, stop reading characteristic and unregister handler
                await characteristic.StopUpdatesAsync();

                characteristic.ValueUpdated -= GetPubKeyPortion;

                // Cut off 'starting' padding from beginning of arduino's public key & convert to byte array
                ArdPubKeyStr = ArdPubKeyStr.Substring(8);

                // Now send the app's public key to arduino via same characteristic
                string appPublicKeyStr = appPublicKey.Q.ToString();
                string appPubKey_x     = appPublicKey.Q.XCoord.ToString();
                string appPubKey_y     = appPublicKey.Q.YCoord.ToString();

                for (int i = 0; i < 64 - appPubKey_x.Length; i++)
                {
                    appPubKey_x = "0" + appPubKey_x;
                }
                for (int i = 0; i < 64 - appPubKey_y.Length; i++)
                {
                    appPubKey_y = "0" + appPubKey_y;
                }

                appPublicKeyStr = appPubKey_x + appPubKey_y;
                char[] pubkey_chars = appPublicKeyStr.ToCharArray();
                byte[] pubkey_bytes = new byte[128];

                for (int i = 0; i < 128; i++)
                {
                    pubkey_bytes[i] = Convert.ToByte(pubkey_chars[i]);
                }

                byte[][] chunks = pubkey_bytes
                                  .Select((c, i) => new { Value = c, Index = i })
                                  .GroupBy(x => x.Index / 16)
                                  .Select(grp => grp.Select(x => x.Value).ToArray())
                                  .ToArray();

                foreach (byte[] b in chunks)
                {
                    await characteristic.WriteAsync(b);
                }

                BigInteger Q_x = new BigInteger(1, StringToByteArray(ArdPubKeyStr.Substring(0, 64)));
                BigInteger Q_y = new BigInteger(1, StringToByteArray(ArdPubKeyStr.Substring(64, 64)));
                ECPoint    Q   = curve.CreatePoint(Q_x, Q_y);

                ECPublicKeyParameters ArdPubKey = new ECPublicKeyParameters(Q, ecDomain);

                // Extract the shared secret for decryption
                IBasicAgreement agreement = new Org.BouncyCastle.Crypto.Agreement.ECDHBasicAgreement();
                agreement.Init(appPrivateKey);
                sharedKey = agreement.CalculateAgreement(ArdPubKey);
                Debug.WriteLine("Shared KEY: " + ByteArrayToString(sharedKey.ToByteArrayUnsigned()));

                characteristic.ValueUpdated += GetEncryptedMessagePortion;
                await characteristic.StartUpdatesAsync();

                return(true);
            }
            catch (DeviceConnectionException)
            {
                Debug.WriteLine("Could not connect to device");
                return(false);
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
                return(false);
            }
        }
    public void OnClickCreateWalletButton()
    {
        if (nodeIP == null)
        {
            return;
        }
        // packet.GetString();
        bool isVerify = false;

        while (!isVerify)
        {
            string sendJson       = null;
            string sendJsonHeader = null;
            string sendJsonBody   = null;

            JsonData packet = new JsonData();
            JsonData header = new JsonData();
            JsonData body   = new JsonData();

            packet["Header"] = header;
            packet["Body"]   = body;

            //"secp256k1" 세부설정.
            X9ECParameters     ec           = SecNamedCurves.GetByName("secp256k1");
            ECDomainParameters domainParams = new ECDomainParameters(ec.Curve, ec.G, ec.N, ec.H);
            SecureRandom       random       = new SecureRandom();

            // Generate EC KeyPair
            ECKeyPairGenerator        keyGen    = new ECKeyPairGenerator();
            ECKeyGenerationParameters keyParams = new ECKeyGenerationParameters(domainParams, random);
            keyGen.Init(keyParams);
            AsymmetricCipherKeyPair keyPair        = keyGen.GenerateKeyPair();
            ECPublicKeyParameters   publicKeyPara  = keyPair.Public as ECPublicKeyParameters;
            ECPrivateKeyParameters  privateKeyPara = keyPair.Private as ECPrivateKeyParameters;


            ECPoint q   = publicKeyPara.Q;
            FpPoint fp  = new FpPoint(ec.Curve, q.AffineXCoord, q.AffineYCoord);
            byte[]  enc = fp.GetEncoded(true);
            string  compressedPubKey = BitConverter.ToString(enc).Replace("-", "");
            //HexStr으로 표현한 값. 이 publicKey로도 서명이 증명가능.


            SHA256 mySHA256         = SHA256Managed.Create();
            byte[] hashPublicKey    = mySHA256.ComputeHash(HexStringTobytes(compressedPubKey));
            string hexHashPublicKey = bytesToHexString(hashPublicKey);
            sendJsonBody = " \"Body\" : { \"Transaction\" : { \"Type\" : 0, \"UserAddress\" : \""
                           + hexHashPublicKey + "\" } }";
            JsonData transaction = new JsonData();
            body["Transaction"]        = transaction;
            transaction["Type"]        = 0;
            transaction["UserAddress"] = hexHashPublicKey;


            //publicKey를 헥사String으로 변환 후 바이트형식으로 인코딩한걸 해쉬
            ECDsaSigner privSigner = new ECDsaSigner();
            privSigner.Init(true, privateKeyPara);
            BigInteger[] signature = privSigner.GenerateSignature(Encoding.ASCII.GetBytes(packet["Body"].ToJson()));
            BigInteger   r         = signature[0];
            BigInteger   s         = signature[1];
            sendJsonHeader = " \"Header\" : { \"Type\" : \"WalletRegist\", \"PublicKey\" : \"" + compressedPubKey +
                             "\", \"EncryptR\" : \"" + bytesToHexString(r.ToByteArray()) + "\", \"EncryptS\" : \"" +
                             bytesToHexString(s.ToByteArray()) + "\" }";
            header["Type"]      = "WalletRegist";
            header["PublicKey"] = compressedPubKey;
            header["EncryptR"]  = bytesToHexString(r.ToByteArray());
            header["EncryptS"]  = bytesToHexString(s.ToByteArray());

            sendJson = "{ " + sendJsonHeader + ", " + sendJsonBody + " }";

            byte[] walletRegistOutput = Encoding.ASCII.GetBytes(packet.ToJson());
            //Json형식  Str를 byte Array로 해서 보낸다.

            /*
             * // 대칭키 인증서 인증이 맞는지 테스트.
             * BigInteger biPublicKey = new BigInteger(HexStringTobytes(compressedPubKey));
             * ECPoint q2 = domainParams.Curve.DecodePoint(biPublicKey.ToByteArray());
             * publicKeyPara = new ECPublicKeyParameters(q2, domainParams);
             *
             * ECDsaSigner pubSigner = new ECDsaSigner();
             * pubSigner.Init(false, publicKeyPara);
             * Debug.Log(pubSigner.VerifySignature(Encoding.ASCII.GetBytes(packet["Body"].ToJson()), r, s));
             */

            Debug.Log(packet.ToJson());

            TcpClient client = new TcpClient(nodeIP, nodePort);
            //TcpClient client = new TcpClient("13.209.78.154", 51166);
            NetworkStream stream = client.GetStream();
            stream.Write(walletRegistOutput, 0, walletRegistOutput.Length);
            System.Array.Clear(buffer, 0, buffer.Length);
            stream.Read(buffer, 0, buffer.Length);

            JsonData registResponse = JsonMapper.ToObject(Encoding.ASCII.GetString(buffer));
            Debug.Log(Encoding.ASCII.GetString(buffer));
            if (registResponse["Body"]["Response"].GetNatural() == 1)
            {
                // 만약 등록되면
                PlayerPrefs.SetString("PublicKey", compressedPubKey);
                PlayerPrefs.SetString("PrivateKey", bytesToHexString(privateKeyPara.D.ToByteArray()));
                PlayerPrefs.SetString("UserAddress", hexHashPublicKey);

                //지갑이 유효하면 while문을 벗어난다.
                isVerify = true;
            }
            client.Close();
            //우선 소켓을 닫는다.
        }
        changeState();
        OnClickHomeButton();
    }
예제 #13
0
        public static AsymmetricKeyParameter CreateKey(
            SubjectPublicKeyInfo keyInfo)
        {
            AlgorithmIdentifier algID  = keyInfo.AlgorithmID;
            DerObjectIdentifier algOid = algID.Algorithm;

            // TODO See RSAUtil.isRsaOid in Java build
            if (algOid.Equals(PkcsObjectIdentifiers.RsaEncryption) ||
                algOid.Equals(X509ObjectIdentifiers.IdEARsa) ||
                algOid.Equals(PkcsObjectIdentifiers.IdRsassaPss) ||
                algOid.Equals(PkcsObjectIdentifiers.IdRsaesOaep))
            {
                RsaPublicKeyStructure pubKey = RsaPublicKeyStructure.GetInstance(
                    keyInfo.ParsePublicKey());

                return(new RsaKeyParameters(false, pubKey.Modulus, pubKey.PublicExponent));
            }
            else if (algOid.Equals(X9ObjectIdentifiers.DHPublicNumber))
            {
                Asn1Sequence seq = Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object());

                DHPublicKey dhPublicKey = DHPublicKey.GetInstance(keyInfo.ParsePublicKey());

                BigInteger y = dhPublicKey.Y.Value;

                if (IsPkcsDHParam(seq))
                {
                    return(ReadPkcsDHParam(algOid, y, seq));
                }

                DHDomainParameters dhParams = DHDomainParameters.GetInstance(seq);

                BigInteger p = dhParams.P.Value;
                BigInteger g = dhParams.G.Value;
                BigInteger q = dhParams.Q.Value;

                BigInteger j = null;
                if (dhParams.J != null)
                {
                    j = dhParams.J.Value;
                }

                DHValidationParameters validation        = null;
                DHValidationParms      dhValidationParms = dhParams.ValidationParms;
                if (dhValidationParms != null)
                {
                    byte[]     seed        = dhValidationParms.Seed.GetBytes();
                    BigInteger pgenCounter = dhValidationParms.PgenCounter.Value;

                    // TODO Check pgenCounter size?

                    validation = new DHValidationParameters(seed, pgenCounter.IntValue);
                }

                return(new DHPublicKeyParameters(y, new DHParameters(p, g, q, j, validation)));
            }
            else if (algOid.Equals(PkcsObjectIdentifiers.DhKeyAgreement))
            {
                Asn1Sequence seq = Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object());

                DerInteger derY = (DerInteger)keyInfo.ParsePublicKey();

                return(ReadPkcsDHParam(algOid, derY.Value, seq));
            }
            else if (algOid.Equals(OiwObjectIdentifiers.ElGamalAlgorithm))
            {
                ElGamalParameter para = new ElGamalParameter(
                    Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
                DerInteger derY = (DerInteger)keyInfo.ParsePublicKey();

                return(new ElGamalPublicKeyParameters(
                           derY.Value,
                           new ElGamalParameters(para.P, para.G)));
            }
            else if (algOid.Equals(X9ObjectIdentifiers.IdDsa) ||
                     algOid.Equals(OiwObjectIdentifiers.DsaWithSha1))
            {
                DerInteger    derY = (DerInteger)keyInfo.ParsePublicKey();
                Asn1Encodable ae   = algID.Parameters;

                DsaParameters parameters = null;
                if (ae != null)
                {
                    DsaParameter para = DsaParameter.GetInstance(ae.ToAsn1Object());
                    parameters = new DsaParameters(para.P, para.Q, para.G);
                }

                return(new DsaPublicKeyParameters(derY.Value, parameters));
            }
            else if (algOid.Equals(X9ObjectIdentifiers.IdECPublicKey))
            {
                X962Parameters para = new X962Parameters(algID.Parameters.ToAsn1Object());

                X9ECParameters x9;
                if (para.IsNamedCurve)
                {
                    x9 = ECKeyPairGenerator.FindECCurveByOid((DerObjectIdentifier)para.Parameters);
                }
                else
                {
                    x9 = new X9ECParameters((Asn1Sequence)para.Parameters);
                }

                Asn1OctetString key  = new DerOctetString(keyInfo.PublicKeyData.GetBytes());
                X9ECPoint       derQ = new X9ECPoint(x9.Curve, key);
                ECPoint         q    = derQ.Point;

                if (para.IsNamedCurve)
                {
                    return(new ECPublicKeyParameters("EC", q, (DerObjectIdentifier)para.Parameters));
                }

                ECDomainParameters dParams = new ECDomainParameters(x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed());
                return(new ECPublicKeyParameters(q, dParams));
            }
            else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001))
            {
                Gost3410PublicKeyAlgParameters gostParams        = Gost3410PublicKeyAlgParameters.GetInstance(algID.Parameters);
                DerObjectIdentifier            publicKeyParamSet = gostParams.PublicKeyParamSet;

                ECDomainParameters ecP = ECGost3410NamedCurves.GetByOid(publicKeyParamSet);
                if (ecP == null)
                {
                    return(null);
                }

                Asn1OctetString key;
                try
                {
                    key = (Asn1OctetString)keyInfo.ParsePublicKey();
                }
                catch (IOException e)
                {
                    throw new ArgumentException("error recovering GOST3410_2001 public key", e);
                }

                int fieldSize = 32;
                int keySize   = 2 * fieldSize;

                byte[] keyEnc = key.GetOctets();
                if (keyEnc.Length != keySize)
                {
                    throw new ArgumentException("invalid length for GOST3410_2001 public key");
                }

                byte[] x9Encoding = new byte[1 + keySize];
                x9Encoding[0] = 0x04;
                for (int i = 1; i <= fieldSize; ++i)
                {
                    x9Encoding[i]             = keyEnc[fieldSize - i];
                    x9Encoding[i + fieldSize] = keyEnc[keySize - i];
                }

                ECPoint q = ecP.Curve.DecodePoint(x9Encoding);

                return(new ECPublicKeyParameters("ECGOST3410", q, publicKeyParamSet));
            }
            else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x94))
            {
                Gost3410PublicKeyAlgParameters algParams = Gost3410PublicKeyAlgParameters.GetInstance(algID.Parameters);

                Asn1OctetString key;
                try
                {
                    key = (Asn1OctetString)keyInfo.ParsePublicKey();
                }
                catch (IOException e)
                {
                    throw new ArgumentException("error recovering GOST3410_94 public key", e);
                }

                byte[] keyBytes = Arrays.Reverse(key.GetOctets()); // was little endian

                BigInteger y = new BigInteger(1, keyBytes);

                return(new Gost3410PublicKeyParameters(y, algParams.PublicKeyParamSet));
            }
            else if (algOid.Equals(EdECObjectIdentifiers.id_X25519))
            {
                return(new X25519PublicKeyParameters(GetRawKey(keyInfo, X25519PublicKeyParameters.KeySize), 0));
            }
            else if (algOid.Equals(EdECObjectIdentifiers.id_X448))
            {
                return(new X448PublicKeyParameters(GetRawKey(keyInfo, X448PublicKeyParameters.KeySize), 0));
            }
            else if (algOid.Equals(EdECObjectIdentifiers.id_Ed25519))
            {
                return(new Ed25519PublicKeyParameters(GetRawKey(keyInfo, Ed25519PublicKeyParameters.KeySize), 0));
            }
            else if (algOid.Equals(EdECObjectIdentifiers.id_Ed448))
            {
                return(new Ed448PublicKeyParameters(GetRawKey(keyInfo, Ed448PublicKeyParameters.KeySize), 0));
            }
            else if (algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256) ||
                     algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512))
            {
                Gost3410PublicKeyAlgParameters gostParams        = Gost3410PublicKeyAlgParameters.GetInstance(algID.Parameters);
                DerObjectIdentifier            publicKeyParamSet = gostParams.PublicKeyParamSet;

                ECGost3410Parameters ecDomainParameters = new ECGost3410Parameters(
                    new ECNamedDomainParameters(publicKeyParamSet, ECGost3410NamedCurves.GetByOid(publicKeyParamSet)),
                    publicKeyParamSet,
                    gostParams.DigestParamSet,
                    gostParams.EncryptionParamSet);

                Asn1OctetString key;
                try
                {
                    key = (Asn1OctetString)keyInfo.ParsePublicKey();
                }
                catch (IOException e)
                {
                    throw new ArgumentException("error recovering GOST3410_2012 public key", e);
                }

                int fieldSize = 32;
                if (algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512))
                {
                    fieldSize = 64;
                }
                int keySize = 2 * fieldSize;

                byte[] keyEnc = key.GetOctets();
                if (keyEnc.Length != keySize)
                {
                    throw new ArgumentException("invalid length for GOST3410_2012 public key");
                }

                byte[] x9Encoding = new byte[1 + keySize];
                x9Encoding[0] = 0x04;
                for (int i = 1; i <= fieldSize; ++i)
                {
                    x9Encoding[i]             = keyEnc[fieldSize - i];
                    x9Encoding[i + fieldSize] = keyEnc[keySize - i];
                }

                ECPoint q = ecDomainParameters.Curve.DecodePoint(x9Encoding);

                return(new ECPublicKeyParameters(q, ecDomainParameters));
            }
            else
            {
                throw new SecurityUtilityException("algorithm identifier in public key not recognised: " + algOid);
            }
        }
        public void TestAlgorithms()
        {
            SecureRandom RANDOM = new SecureRandom();

            //
            // RSA parameters
            //
            BigInteger rsaMod    = new BigInteger("a7295693155b1813bb84877fb45343556e0568043de5910872a3a518cc11e23e2db74eaf4545068c4e3d258a2718fbacdcc3eafa457695b957e88fbf110aed049a992d9c430232d02f3529c67a3419935ea9b569f85b1bcd37de6b899cd62697e843130ff0529d09c97d813cb15f293751ff56f943fbdabb63971cc7f4f6d5bff1594416b1f5907bde5a84a44f9802ef29b43bda1960f948f8afb8766c1ab80d32eec88ed66d0b65aebe44a6d0b3c5e0ab051aaa1b912fbcc17b8e751ddecc5365b6db6dab0020c3057db4013a51213a5798a3aab67985b0f4d88627a54a0f3f0285fbcb4afdfeb65cb153af66825656d43238b75503231500753f4e421e3c57", 16);
            BigInteger rsaPubExp = new BigInteger("10001", 16);

            BigInteger rsaPrivExp  = new BigInteger("65dad56ac7df7abb434e4cb5eeadb16093aa6da7f0033aad3815289b04757d32bfee6ade7749c8e4a323b5050a2fb9e2a99e23469e1ed4ba5bab54336af20a5bfccb8b3424cc6923db2ffca5787ed87aa87aa614cd04cedaebc8f623a2d2063017910f436dff18bb06f01758610787f8b258f0a8efd8bd7de30007c47b2a1031696c7d6523bc191d4d918927a7e0b09584ed205bd2ff4fc4382678df82353f7532b3bbb81d69e3f39070aed3fb64fce032a089e8e64955afa5213a6eb241231bd98d702fba725a9b205952fda186412d9e0d9344d2998c455ad8c2bae85ee672751466d5288304032b5b7e02f7e558c7af82c7fbf58eea0bb4ef0f001e6cd0a9", 16);
            BigInteger rsaPrivP    = new BigInteger("d4fd9ac3474fb83aaf832470643609659e511b322632b239b688f3cd2aad87527d6cf652fb9c9ca67940e84789444f2e99b0cb0cfabbd4de95396106c865f38e2fb7b82b231260a94df0e01756bf73ce0386868d9c41645560a81af2f53c18e4f7cdf3d51d80267372e6e0216afbf67f655c9450769cca494e4f6631b239ce1b", 16);
            BigInteger rsaPrivQ    = new BigInteger("c8eaa0e2a1b3a4412a702bccda93f4d150da60d736c99c7c566fdea4dd1b401cbc0d8c063daaf0b579953d36343aa18b33dbf8b9eae94452490cc905245f8f7b9e29b1a288bc66731a29e1dd1a45c9fd7f8238ff727adc49fff73991d0dc096206b9d3a08f61e7462e2b804d78cb8c5eccdb9b7fbd2ad6a8fea46c1053e1be75", 16);
            BigInteger rsaPrivDP   = new BigInteger("10edcb544421c0f9e123624d1099feeb35c72a8b34e008ac6fa6b90210a7543f293af4e5299c8c12eb464e70092805c7256e18e5823455ba0f504d36f5ccacac1b7cd5c58ff710f9c3f92646949d88fdd1e7ea5fed1081820bb9b0d2a8cd4b093fecfdb96dabd6e28c3a6f8c186dc86cddc89afd3e403e0fcf8a9e0bcb27af0b", 16);
            BigInteger rsaPrivDQ   = new BigInteger("97fc25484b5a415eaa63c03e6efa8dafe9a1c8b004d9ee6e80548fefd6f2ce44ee5cb117e77e70285798f57d137566ce8ea4503b13e0f1b5ed5ca6942537c4aa96b2a395782a4cb5b58d0936e0b0fa63b1192954d39ced176d71ef32c6f42c84e2e19f9d4dd999c2151b032b97bd22aa73fd8c5bcd15a2dca4046d5acc997021", 16);
            BigInteger rsaPrivQinv = new BigInteger("4bb8064e1eff7e9efc3c4578fcedb59ca4aef0993a8312dfdcb1b3decf458aa6650d3d0866f143cbf0d3825e9381181170a0a1651eefcd7def786b8eb356555d9fa07c85b5f5cbdd74382f1129b5e36b4166b6cc9157923699708648212c484958351fdc9cf14f218dbe7fbf7cbd93a209a4681fe23ceb44bab67d66f45d1c9d", 16);

            RsaKeyParameters           rsaPublic  = new RsaKeyParameters(false, rsaMod, rsaPubExp);
            RsaPrivateCrtKeyParameters rsaPrivate = new RsaPrivateCrtKeyParameters(
                rsaMod, rsaPubExp, rsaPrivExp, rsaPrivP, rsaPrivQ, rsaPrivDP, rsaPrivDQ, rsaPrivQinv);

            //
            // ECDSA parameters
            //
            BigInteger ECParraGX = new BigInteger(Base64.Decode("D/qWPNyogWzMM7hkK+35BcPTWFc9Pyf7vTs8uaqv"));
            BigInteger ECParraGY = new BigInteger(Base64.Decode("AhQXGxb1olGRv6s1LPRfuatMF+cx3ZTGgzSE/Q5R"));
            BigInteger ECParraH  = new BigInteger(Base64.Decode("AQ=="));
            BigInteger ECParraN  = new BigInteger(Base64.Decode("f///////////////f///nl6an12QcfvRUiaIkJ0L"));
            BigInteger ECPubQX   = new BigInteger(Base64.Decode("HWWi17Yb+Bm3PYr/DMjLOYNFhyOwX1QY7ZvqqM+l"));
            BigInteger ECPubQY   = new BigInteger(Base64.Decode("JrlJfxu3WGhqwtL/55BOs/wsUeiDFsvXcGhB8DGx"));
            BigInteger ECPrivD   = new BigInteger(Base64.Decode("GYQmd/NF1B+He1iMkWt3by2Az6Eu07t0ynJ4YCAo"));

            FpCurve curve = new FpCurve(
                new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q
                new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16),         // a
                new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16),         // b
                ECParraN, ECParraH);

            ECDomainParameters ecDomain = new ECDomainParameters(
                curve,
                curve.ValidatePoint(ECParraGX, ECParraGY),
                ECParraN, ECParraH);

            ECPublicKeyParameters ecPub = new ECPublicKeyParameters(
                curve.ValidatePoint(ECPubQX, ECPubQY),
                ecDomain);

            ECPrivateKeyParameters ecPriv = new ECPrivateKeyParameters(ECPrivD, ecDomain);

            //
            // DSA parameters
            //
            BigInteger DSAParaG    = new BigInteger(Base64.Decode("AL0fxOTq10OHFbCf8YldyGembqEu08EDVzxyLL29Zn/t4It661YNol1rnhPIs+cirw+yf9zeCe+KL1IbZ/qIMZM="));
            BigInteger DSAParaP    = new BigInteger(Base64.Decode("AM2b/UeQA+ovv3dL05wlDHEKJ+qhnJBsRT5OB9WuyRC830G79y0R8wuq8jyIYWCYcTn1TeqVPWqiTv6oAoiEeOs="));
            BigInteger DSAParaQ    = new BigInteger(Base64.Decode("AIlJT7mcKL6SUBMmvm24zX1EvjNx"));
            BigInteger DSAPublicY  = new BigInteger(Base64.Decode("TtWy2GuT9yGBWOHi1/EpCDa/bWJCk2+yAdr56rAcqP0eHGkMnA9s9GJD2nGU8sFjNHm55swpn6JQb8q0agrCfw=="));
            BigInteger DsaPrivateX = new BigInteger(Base64.Decode("MMpBAxNlv7eYfxLTZ2BItJeD31A="));

            DsaParameters           para    = new DsaParameters(DSAParaP, DSAParaQ, DSAParaG);
            DsaPrivateKeyParameters dsaPriv = new DsaPrivateKeyParameters(DsaPrivateX, para);
            DsaPublicKeyParameters  dsaPub  = new DsaPublicKeyParameters(DSAPublicY, para);

            //
            // ECGOST3410 parameters
            //
            IAsymmetricCipherKeyPairGenerator ecGostKpg = GeneratorUtilities.GetKeyPairGenerator("ECGOST3410");

            ecGostKpg.Init(
                new ECKeyGenerationParameters(
                    CryptoProObjectIdentifiers.GostR3410x2001CryptoProA,
                    RANDOM));

            AsymmetricCipherKeyPair ecGostPair = ecGostKpg.GenerateKeyPair();

            IAsymmetricCipherKeyPairGenerator ed25519Kpg = GeneratorUtilities.GetKeyPairGenerator("Ed25519");

            ed25519Kpg.Init(new Ed25519KeyGenerationParameters(RANDOM));
            AsymmetricCipherKeyPair ed25519Pair = ed25519Kpg.GenerateKeyPair();

            IAsymmetricCipherKeyPairGenerator ed448Kpg = GeneratorUtilities.GetKeyPairGenerator("Ed448");

            ed448Kpg.Init(new Ed448KeyGenerationParameters(RANDOM));
            AsymmetricCipherKeyPair ed448Pair = ed448Kpg.GenerateKeyPair();

            //
            // GOST3410 parameters
            //
            IAsymmetricCipherKeyPairGenerator gostKpg = GeneratorUtilities.GetKeyPairGenerator("GOST3410");

            gostKpg.Init(new Gost3410KeyGenerationParameters(RANDOM, CryptoProObjectIdentifiers.GostR3410x94CryptoProA));
            AsymmetricCipherKeyPair gostPair = gostKpg.GenerateKeyPair();

            //
            // SM2 parameters
            //
            BigInteger SM2_ECC_P  = new BigInteger("8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3", 16);
            BigInteger SM2_ECC_A  = new BigInteger("787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498", 16);
            BigInteger SM2_ECC_B  = new BigInteger("63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A", 16);
            BigInteger SM2_ECC_N  = new BigInteger("8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7", 16);
            BigInteger SM2_ECC_H  = BigInteger.One;
            BigInteger SM2_ECC_GX = new BigInteger("421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D", 16);
            BigInteger SM2_ECC_GY = new BigInteger("0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2", 16);

            ECCurve            sm2Curve  = new FpCurve(SM2_ECC_P, SM2_ECC_A, SM2_ECC_B, SM2_ECC_N, SM2_ECC_H);
            ECPoint            sm2G      = sm2Curve.CreatePoint(SM2_ECC_GX, SM2_ECC_GY);
            ECDomainParameters sm2Domain = new ECDomainParameters(sm2Curve, sm2G, SM2_ECC_N, SM2_ECC_H);

            ECKeyPairGenerator sm2Kpg = new ECKeyPairGenerator();

            sm2Kpg.Init(new ECKeyGenerationParameters(sm2Domain, RANDOM));
            AsymmetricCipherKeyPair sm2Pair = sm2Kpg.GenerateKeyPair();


            //
            // signer loop
            //
            byte[] shortMsg = new byte[] { 1, 4, 5, 6, 8, 8, 4, 2, 1, 3 };
            byte[] longMsg  = new byte[100];
            RANDOM.NextBytes(longMsg);

            foreach (string algorithm in SignerUtilities.Algorithms)
            {
                ISigner signer = SignerUtilities.GetSigner(algorithm);

                string upper   = algorithm.ToUpper(CultureInfo.InvariantCulture);
                int    withPos = upper.LastIndexOf("WITH");

                string cipherName = withPos < 0
                    ?   upper
                    :   upper.Substring(withPos + "WITH".Length);

                ICipherParameters signParams = null, verifyParams = null;

                if (cipherName == "RSA" || cipherName == "RSAANDMGF1")
                {
                    signParams   = rsaPrivate;
                    verifyParams = rsaPublic;
                }
                else if (cipherName == "ECDSA" ||
                         cipherName == "CVC-ECDSA" ||
                         cipherName == "PLAIN-ECDSA")
                {
                    signParams   = ecPriv;
                    verifyParams = ecPub;
                }
                else if (cipherName == "DSA")
                {
                    signParams   = dsaPriv;
                    verifyParams = dsaPub;
                }
                else if (cipherName == "ECGOST3410")
                {
                    signParams   = ecGostPair.Private;
                    verifyParams = ecGostPair.Public;
                }
                else if (cipherName == "ED25519")
                {
                    signParams   = ed25519Pair.Private;
                    verifyParams = ed25519Pair.Public;
                }
                else if (cipherName == "ED448")
                {
                    signParams   = ed448Pair.Private;
                    verifyParams = ed448Pair.Public;
                }
                else if (cipherName == "GOST3410")
                {
                    signParams   = gostPair.Private;
                    verifyParams = gostPair.Public;
                }
                else if (cipherName == "SM2")
                {
                    signParams   = sm2Pair.Private;
                    verifyParams = sm2Pair.Public;
                }
                else
                {
                    Assert.Fail("Unknown algorithm encountered: " + cipherName);
                }

                signer.Init(true, signParams);
                foreach (byte b in shortMsg)
                {
                    signer.Update(b);
                }
                signer.BlockUpdate(longMsg, 0, longMsg.Length);
                byte[] sig = signer.GenerateSignature();

                signer.Init(false, verifyParams);
                foreach (byte b in shortMsg)
                {
                    signer.Update(b);
                }
                signer.BlockUpdate(longMsg, 0, longMsg.Length);

                Assert.IsTrue(signer.VerifySignature(sig), cipherName + " signer " + algorithm + " failed.");
            }
        }
        public SimpleTestResult EncodeDecodePublicLW(string oidStr, DerObjectIdentifier digest)
        {
            DerObjectIdentifier       oid        = ECGost3410NamedCurves.GetOid(oidStr);
            ECNamedDomainParameters   ecp        = new ECNamedDomainParameters(oid, ECGost3410NamedCurves.GetByOidX9(oid));
            ECGost3410Parameters      gostParams = new ECGost3410Parameters(ecp, oid, digest, null);
            ECKeyGenerationParameters parameters = new ECKeyGenerationParameters(gostParams, new SecureRandom());
            ECKeyPairGenerator        engine     = new ECKeyPairGenerator();

            engine.Init(parameters);
            AsymmetricCipherKeyPair pair = engine.GenerateKeyPair();
            ECPublicKeyParameters   generatedKeyParameters = (ECPublicKeyParameters)pair.Public;

            SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(generatedKeyParameters);

            ECPublicKeyParameters recoveredKeyParameters = (ECPublicKeyParameters)PublicKeyFactory.CreateKey(info);

            {
                // Specifically cast and test gost parameters.
                ECGost3410Parameters gParam = (ECGost3410Parameters)generatedKeyParameters.Parameters;
                ECGost3410Parameters rParam = (ECGost3410Parameters)recoveredKeyParameters.Parameters;

                bool ok = SafeEquals(gParam.DigestParamSet, rParam.DigestParamSet) &&
                          SafeEquals(gParam.EncryptionParamSet, rParam.EncryptionParamSet) &&
                          SafeEquals(gParam.PublicKeyParamSet, rParam.PublicKeyParamSet);

                if (!ok)
                {
                    return(new SimpleTestResult(false, "GOST parameters does not match"));
                }
            }

            if (!((ECGost3410Parameters)recoveredKeyParameters.Parameters).Name.Equals(
                    ((ECGost3410Parameters)generatedKeyParameters.Parameters).Name))
            {
                return(new SimpleTestResult(false, "Name does not match"));
            }

            if (recoveredKeyParameters.IsPrivate != generatedKeyParameters.IsPrivate)
            {
                return(new SimpleTestResult(false, "isPrivate does not match"));
            }

            if (!Arrays.AreEqual(
                    recoveredKeyParameters.Q.GetEncoded(true),
                    generatedKeyParameters.Q.GetEncoded(true)))
            {
                return(new SimpleTestResult(false, "Q does not match"));
            }

            if (!recoveredKeyParameters.Parameters.Curve.Equals(generatedKeyParameters.Parameters.Curve))
            {
                return(new SimpleTestResult(false, "Curve does not match"));
            }

            if (!Arrays.AreEqual(
                    recoveredKeyParameters.Parameters.G.GetEncoded(true),
                    generatedKeyParameters.Parameters.G.GetEncoded(true)))
            {
                return(new SimpleTestResult(false, "G does not match"));
            }

            if (!recoveredKeyParameters.Parameters.H.Equals(generatedKeyParameters.Parameters.H))
            {
                return(new SimpleTestResult(false, "H does not match"));
            }

            if (!recoveredKeyParameters.Parameters.HInv.Equals(generatedKeyParameters.Parameters.HInv))
            {
                return(new SimpleTestResult(false, "Hinv does not match"));
            }

            if (!recoveredKeyParameters.Parameters.N.Equals(generatedKeyParameters.Parameters.N))
            {
                return(new SimpleTestResult(false, "N does not match"));
            }

            if (!Arrays.AreEqual(recoveredKeyParameters.Parameters.GetSeed(), generatedKeyParameters.Parameters.GetSeed()))
            {
                return(new SimpleTestResult(false, "Seed does not match"));
            }

            return(new SimpleTestResult(true, null));
        }
예제 #16
0
        public static void FullSignatureTest(byte[] hash)
        {
            X9ECParameters     ecParams         = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1");
            ECDomainParameters domainParameters = new ECDomainParameters(ecParams.Curve,
                                                                         ecParams.G, ecParams.N, ecParams.H,
                                                                         ecParams.GetSeed());
            ECKeyGenerationParameters keyGenParams =
                new ECKeyGenerationParameters(domainParameters, new SecureRandom());

            AsymmetricCipherKeyPair keyPair;
            ECKeyPairGenerator      generator = new ECKeyPairGenerator();

            generator.Init(keyGenParams);
            keyPair = generator.GenerateKeyPair();

            ECPrivateKeyParameters privateKey = (ECPrivateKeyParameters)keyPair.Private;
            ECPublicKeyParameters  publicKey  = (ECPublicKeyParameters)keyPair.Public;

            Console.WriteLine("Generated private key: " + ToHex(privateKey.D.ToByteArrayUnsigned()));
            Console.WriteLine("Generated public key: " + ToHex(publicKey.Q.GetEncoded()));

            ECDsaSigner signer = new ECDsaSigner();

            signer.Init(true, privateKey);
            BigInteger[] sig = signer.GenerateSignature(hash);

            int recid = -1;

            for (int rec = 0; rec < 4; rec++)
            {
                try
                {
                    ECPoint Q = ECDSA_SIG_recover_key_GFp(sig, hash, rec, true);
                    if (ToHex(publicKey.Q.GetEncoded()).Equals(ToHex(Q.GetEncoded())))
                    {
                        recid = rec;
                        break;
                    }
                }
                catch (Exception)
                {
                    continue;
                }
            }
            if (recid < 0)
            {
                throw new Exception("Did not find proper recid");
            }

            byte[] fullSigBytes = new byte[65];
            fullSigBytes[0] = (byte)(27 + recid);
            Buffer.BlockCopy(sig[0].ToByteArrayUnsigned(), 0, fullSigBytes, 1, 32);
            Buffer.BlockCopy(sig[1].ToByteArrayUnsigned(), 0, fullSigBytes, 33, 32);

            Console.WriteLine("Generated full signature: " + Convert.ToBase64String(fullSigBytes));

            byte[] sigBytes = new byte[64];
            Buffer.BlockCopy(sig[0].ToByteArrayUnsigned(), 0, sigBytes, 0, 32);
            Buffer.BlockCopy(sig[1].ToByteArrayUnsigned(), 0, sigBytes, 32, 32);

            ECPoint genQ = ECDSA_SIG_recover_key_GFp(sig, hash, recid, false);

            Console.WriteLine("Generated signature verifies: " + VerifySignature(genQ.GetEncoded(), hash, sigBytes));
        }
        public void EcGOST34102012256Test()
        {
            BigInteger r = new BigInteger("29700980915817952874371204983938256990422752107994319651632687982059210933395");
            BigInteger s = new BigInteger("574973400270084654178925310019147038455227042649098563933718999175515839552");

            BigInteger e = new BigInteger("20798893674476452017134061561508270130637142515379653289952617252661468872421");

            byte[]       kData = BigIntegers.AsUnsignedByteArray(new BigInteger("53854137677348463731403841147996619241504003434302020712960838528893196233395"));
            SecureRandom k     = new TestRandomBigInteger(kData);

            BigInteger mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041");
            BigInteger mod_q = new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619");


            ECCurve curve = new FpCurve(
                mod_p,
                new BigInteger("7"),                                                                             // a
                new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414"), // b
                mod_q, BigInteger.One);

            ECDomainParameters spec = new ECDomainParameters(curve,
                                                             curve.CreatePoint(
                                                                 new BigInteger("2"),                                                                             // x
                                                                 new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280")), // y
                                                             mod_q, BigInteger.One);

            ECPrivateKeyParameters privateKey = new ECPrivateKeyParameters(
                new BigInteger("55441196065363246126355624130324183196576709222340016572108097750006097525544"), // d
                spec);

            ECPublicKeyParameters publicKey = new ECPublicKeyParameters(curve.CreatePoint(
                                                                            new BigInteger("57520216126176808443631405023338071176630104906313632182896741342206604859403"),  // x
                                                                            new BigInteger("17614944419213781543809391949654080031942662045363639260709847859438286763994")), // y
                                                                        spec);

            ECGOST3410_2012Signer signer = new ECGOST3410_2012Signer();

            signer.Init(true, new ParametersWithRandom(privateKey, k));

            byte[] rev     = e.ToByteArray();
            byte[] message = new byte[rev.Length];
            for (int i = 0; i != rev.Length; i++)
            {
                message[i] = rev[rev.Length - 1 - i];
            }
            BigInteger[] sig = signer.GenerateSignature(message);

            signer.Init(false, publicKey);

            if (!signer.VerifySignature(message, sig[0], sig[1]))
            {
                Fail("ECGOST3410 2012 verification failed");
            }

            if (!r.Equals(sig[0]))
            {
                Fail(
                    ": r component wrong." + Environment.NewLine
                    + " expecting: " + r + Environment.NewLine
                    + " got      : " + sig[0]);
            }

            if (!s.Equals(sig[1]))
            {
                Fail(
                    ": s component wrong." + Environment.NewLine
                    + " expecting: " + s + Environment.NewLine
                    + " got      : " + sig[1]);
            }


            // 256Bit
            {
                DerObjectIdentifier     oid        = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256_paramSetA;
                ECNamedDomainParameters ecp        = new ECNamedDomainParameters(oid, ECGost3410NamedCurves.GetByOid(oid));
                ECGOST3410Parameters    gostParams = new ECGOST3410Parameters(ecp, oid,
                                                                              RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256, null);
                ECKeyGenerationParameters parameters = new ECKeyGenerationParameters(gostParams, new SecureRandom());
                ECKeyPairGenerator        engine     = new ECKeyPairGenerator();
                engine.Init(parameters);
                AsymmetricCipherKeyPair pair = engine.GenerateKeyPair();
                SignatureGost12Test("ECGOST3410-2012-256", 64, pair);
            }

            // 512Bit


            {
                DerObjectIdentifier     oid        = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512_paramSetA;
                ECNamedDomainParameters ecp        = new ECNamedDomainParameters(oid, ECGost3410NamedCurves.GetByOid(oid));
                ECGOST3410Parameters    gostParams = new ECGOST3410Parameters(ecp, oid,
                                                                              RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512, null);
                ECKeyGenerationParameters parameters = new ECKeyGenerationParameters(gostParams, new SecureRandom());
                ECKeyPairGenerator        engine     = new ECKeyPairGenerator();
                engine.Init(parameters);
                AsymmetricCipherKeyPair pair = engine.GenerateKeyPair();

                SignatureGost12Test("ECGOST3410-2012-512", 128, pair);
            }
        }
예제 #18
0
        public void Backdoor()
        {
            var random = new SecureRandom();
            var curve  = CustomNamedCurves.GetByName("secp521r1");
            var gen    = new ECKeyPairGenerator("ECDSA");
            var G      = curve.G;
            var N      = curve.N;
            var paramz = new ECDomainParameters(curve.Curve, G, N);

            gen.Init(new ECKeyGenerationParameters(paramz, random));

            var kCalc = new RandomDsaKCalculator();             // kCalc generates random values [1, N-1]

            kCalc.Init(N, random);

            var attackersKeyPair = gen.GenerateKeyPair();

            var v = ((ECPrivateKeyParameters)attackersKeyPair.Private).D;        //attacker's private
            var V = G.Multiply(v);                                               //attackers public

            var usersKeyPair = gen.GenerateKeyPair();                            //user's keypair
            var D            = ((ECPrivateKeyParameters)usersKeyPair.Private).D; //user's private
            var Q            = ((ECPublicKeyParameters)usersKeyPair.Public).Q;   //user's public


            const string message1 = "First message to sign";
            var          m1       = new BigInteger(1, Hash(Encoding.UTF8.GetBytes(message1))); // hash of m1

            //Generate signature 1
            var k1 = kCalc.NextK();             // k1 is true random
            var signaturePoint1 = G.Multiply(k1).Normalize();

            //(r1, s1) - signature 1
            var r1 = signaturePoint1.AffineXCoord.ToBigInteger().Mod(N);
            var s1 = k1.ModInverse(N).Multiply(m1.Add(D.Multiply(r1)));


            //verify signature 1
            var w            = s1.ModInverse(N);
            var u1           = m1.Multiply(w).Mod(N);
            var u2           = r1.Multiply(w).Mod(N);
            var verifyPoint1 = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2).Normalize();

            var valid1 = verifyPoint1.AffineXCoord.ToBigInteger().Mod(N).Equals(r1);


            //Generate signature 2
            const string message2 = "Second message to sign";
            var          m2       = new BigInteger(1, Hash(Encoding.UTF8.GetBytes(message2))); // hash of m2

            //here we generate a,b,h,e < N using seed = hash(m2)
            kCalc.Init(N, new SecureRandom(new SeededGenerator(Hash(Encoding.UTF8.GetBytes(message2)))));

            var a = kCalc.NextK();
            var b = kCalc.NextK();
            var h = kCalc.NextK();
            var e = kCalc.NextK();

            //u,j - true random
            var u = (random.Next() % 2) == 1 ? BigInteger.One : BigInteger.Zero;
            var j = (random.Next() % 2) == 1 ? BigInteger.One : BigInteger.Zero;

            //compute hidden field element
            var Z = G.Multiply(k1).Multiply(a)
                    .Add(V.Multiply(k1).Multiply(b))
                    .Add(G.Multiply(h).Multiply(j))
                    .Add(V.Multiply(e).Multiply(u))
                    .Normalize();

            var zX = Z.AffineXCoord.ToBigInteger().ToByteArray();

            var hash            = Hash(zX);
            var k2              = new BigInteger(1, hash);
            var signaturePoint2 = G.Multiply(k2).Normalize();

            //(r2, s2) = signature 2
            var r2 = signaturePoint2.AffineXCoord.ToBigInteger().Mod(N);
            var s2 = k2.ModInverse(N).Multiply(m2.Add(D.Multiply(r2)));

            //verify signature 2

            w  = s2.ModInverse(N);
            u1 = m2.Multiply(w).Mod(N);
            u2 = r2.Multiply(w).Mod(N);
            var verifyPoint2 = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2).Normalize();

            var valid2 = verifyPoint2.AffineXCoord.ToBigInteger().Mod(N).Equals(r2);

            if (valid1 && valid2)
            {
                //compute user's private key
                var d = ExtractUsersPrivateKey(G, N, message1, message2, r1, s1, r2, s2, v, V, Q);
                Console.WriteLine("Ecdsa private key restored: {0}", d.Equals(D));
            }
            else
            {
                Console.WriteLine("Something's wrong");
            }
        }
예제 #19
0
        public static AsymmetricKeyParameter CreateKey(
            PrivateKeyInfo keyInfo)
        {
            AlgorithmIdentifier algID  = keyInfo.AlgorithmID;
            DerObjectIdentifier algOid = algID.ObjectID;

            // TODO See RSAUtil.isRsaOid in Java build
            if (algOid.Equals(PkcsObjectIdentifiers.RsaEncryption) ||
                algOid.Equals(X509ObjectIdentifiers.IdEARsa) ||
                algOid.Equals(PkcsObjectIdentifiers.IdRsassaPss) ||
                algOid.Equals(PkcsObjectIdentifiers.IdRsaesOaep))
            {
                RsaPrivateKeyStructure keyStructure = new RsaPrivateKeyStructure(
                    Asn1Sequence.GetInstance(keyInfo.PrivateKey));

                return(new RsaPrivateCrtKeyParameters(
                           keyStructure.Modulus,
                           keyStructure.PublicExponent,
                           keyStructure.PrivateExponent,
                           keyStructure.Prime1,
                           keyStructure.Prime2,
                           keyStructure.Exponent1,
                           keyStructure.Exponent2,
                           keyStructure.Coefficient));
            }
            // TODO?
//			else if (algOid.Equals(X9ObjectIdentifiers.DHPublicNumber))
            else if (algOid.Equals(PkcsObjectIdentifiers.DhKeyAgreement))
            {
                DHParameter para = new DHParameter(
                    Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
                DerInteger derX = (DerInteger)keyInfo.PrivateKey;

                BigInteger   lVal     = para.L;
                int          l        = lVal == null ? 0 : lVal.IntValue;
                DHParameters dhParams = new DHParameters(para.P, para.G, null, l);

                return(new DHPrivateKeyParameters(derX.Value, dhParams, algOid));
            }
            else if (algOid.Equals(OiwObjectIdentifiers.ElGamalAlgorithm))
            {
                ElGamalParameter para = new ElGamalParameter(
                    Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
                DerInteger derX = (DerInteger)keyInfo.PrivateKey;

                return(new ElGamalPrivateKeyParameters(
                           derX.Value,
                           new ElGamalParameters(para.P, para.G)));
            }
            else if (algOid.Equals(X9ObjectIdentifiers.IdDsa))
            {
                DerInteger    derX = (DerInteger)keyInfo.PrivateKey;
                Asn1Encodable ae   = algID.Parameters;

                DsaParameters parameters = null;
                if (ae != null)
                {
                    DsaParameter para = DsaParameter.GetInstance(ae.ToAsn1Object());
                    parameters = new DsaParameters(para.P, para.Q, para.G);
                }

                return(new DsaPrivateKeyParameters(derX.Value, parameters));
            }
            else if (algOid.Equals(X9ObjectIdentifiers.IdECPublicKey))
            {
                X962Parameters para = new X962Parameters(algID.Parameters.ToAsn1Object());
                X9ECParameters ecP;

                if (para.IsNamedCurve)
                {
                    ecP = ECKeyPairGenerator.FindECCurveByOid((DerObjectIdentifier)para.Parameters);
                }
                else
                {
                    ecP = new X9ECParameters((Asn1Sequence)para.Parameters);
                }

                ECDomainParameters dParams = new ECDomainParameters(
                    ecP.Curve,
                    ecP.G,
                    ecP.N,
                    ecP.H,
                    ecP.GetSeed());

                ECPrivateKeyStructure ec = new ECPrivateKeyStructure(
                    Asn1Sequence.GetInstance(keyInfo.PrivateKey));

                return(new ECPrivateKeyParameters(ec.GetKey(), dParams));
            }
            else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001))
            {
                Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters(
                    Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));

                ECPrivateKeyStructure ec = new ECPrivateKeyStructure(
                    Asn1Sequence.GetInstance(keyInfo.PrivateKey));

                ECDomainParameters ecP = ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet);

                if (ecP == null)
                {
                    return(null);
                }

                return(new ECPrivateKeyParameters("ECGOST3410", ec.GetKey(), gostParams.PublicKeyParamSet));
            }
            else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x94))
            {
                Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters(
                    Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));

                DerOctetString derX     = (DerOctetString)keyInfo.PrivateKey;
                byte[]         keyEnc   = derX.GetOctets();
                byte[]         keyBytes = new byte[keyEnc.Length];

                for (int i = 0; i != keyEnc.Length; i++)
                {
                    keyBytes[i] = keyEnc[keyEnc.Length - 1 - i];                     // was little endian
                }

                BigInteger x = new BigInteger(1, keyBytes);

                return(new Gost3410PrivateKeyParameters(x, gostParams.PublicKeyParamSet));
            }
            else
            {
                throw new SecurityUtilityException("algorithm identifier in key not recognised");
            }
        }
예제 #20
0
        public static byte[] HandleKey(byte[] key, byte[] secretKey)
        {
            Asn1InputStream inputStream = new Asn1InputStream(key);
            Asn1Object      o1          = inputStream.ReadObject();
            DerSequence     seq         = o1 as DerSequence;

            DerInteger x = seq[2] as DerInteger;
            DerInteger y = seq[3] as DerInteger;

            X9ECParameters     p = CustomNamedCurves.GetByName("secp521r1");
            ECDomainParameters domainParameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H);

            ECPoint point = p.Curve.CreatePoint(x.Value, y.Value);
            ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(point, domainParameters);

            ECKeyPairGenerator generator = new ECKeyPairGenerator();

            generator.Init(new ECKeyGenerationParameters(publicKeyParameters.Parameters, new SecureRandom()));
            AsymmetricCipherKeyPair keyPair = generator.GenerateKeyPair();

            ECDHBasicAgreement basicAgreement = new ECDHBasicAgreement();

            basicAgreement.Init(keyPair.Private);
            BigInteger agreement = basicAgreement.CalculateAgreement(publicKeyParameters);

            byte[] agreementBytes = agreement.ToByteArray();
            if (agreementBytes.Length == 65)
            {
                byte[] newAgreement = new byte[66];
                Array.Copy(agreementBytes, 0, newAgreement, 1, 65);
                agreementBytes = newAgreement;
            }

            Sha512Digest sha512 = new Sha512Digest();

            byte[] hash = new byte[sha512.GetDigestSize()];
            sha512.BlockUpdate(agreementBytes, 0, agreementBytes.Length);
            sha512.DoFinal(hash, 0);

            byte[] secret = new byte[secretKey.Length];
            for (int i = 0; i < secret.Length; i++)
            {
                secret[i]  = secretKey[i];
                secret[i] ^= hash[i];
            }

            ECPublicKeyParameters publicKey = keyPair.Public as ECPublicKeyParameters;

            MemoryStream         keyStream = new MemoryStream();
            DerSequenceGenerator gen2      = new DerSequenceGenerator(keyStream);

            gen2.AddObject(new DerBitString(new byte[] { 0x00 }, 7));
            gen2.AddObject(new DerInteger(new byte[] { 0x41 }));
            gen2.AddObject(new DerInteger(publicKey.Q.XCoord.ToBigInteger()));
            gen2.AddObject(new DerInteger(publicKey.Q.YCoord.ToBigInteger()));
            gen2.Close();

            MemoryStream memoryStream = new MemoryStream();

            DerSequenceGenerator gen1 = new DerSequenceGenerator(memoryStream);

            gen1.AddObject(new DerObjectIdentifier("2.16.840.1.101.3.4.2.3"));
            gen1.AddObject(new DerOctetString(keyStream.ToArray()));
            gen1.AddObject(new DerOctetString(secret));
            gen1.Close();

            byte[] result = memoryStream.ToArray();

            memoryStream.Close();
            keyStream.Close();

            return(result);
        }
예제 #21
0
        /**
         * Create a PrivateKeyInfo representation of a private key with attributes.
         *
         * @param privateKey the key to be encoded into the info object.
         * @param attributes the set of attributes to be included.
         * @return the appropriate PrivateKeyInfo
         * @throws java.io.IOException on an error encoding the key
         */
        public static PrivateKeyInfo CreatePrivateKeyInfo(AsymmetricKeyParameter privateKey, Asn1Set attributes)
        {
            if (privateKey == null)
            {
                throw new ArgumentNullException("privateKey");
            }
            if (!privateKey.IsPrivate)
            {
                throw new ArgumentException("Public key passed - private key expected", "privateKey");
            }

            if (privateKey is ElGamalPrivateKeyParameters)
            {
                ElGamalPrivateKeyParameters _key = (ElGamalPrivateKeyParameters)privateKey;
                ElGamalParameters           egp  = _key.Parameters;
                return(new PrivateKeyInfo(
                           new AlgorithmIdentifier(OiwObjectIdentifiers.ElGamalAlgorithm, new ElGamalParameter(egp.P, egp.G).ToAsn1Object()),
                           new DerInteger(_key.X),
                           attributes));
            }

            if (privateKey is DsaPrivateKeyParameters)
            {
                DsaPrivateKeyParameters _key = (DsaPrivateKeyParameters)privateKey;
                DsaParameters           dp   = _key.Parameters;
                return(new PrivateKeyInfo(
                           new AlgorithmIdentifier(X9ObjectIdentifiers.IdDsa, new DsaParameter(dp.P, dp.Q, dp.G).ToAsn1Object()),
                           new DerInteger(_key.X),
                           attributes));
            }

            if (privateKey is DHPrivateKeyParameters)
            {
                DHPrivateKeyParameters _key = (DHPrivateKeyParameters)privateKey;

                DHParameter p = new DHParameter(
                    _key.Parameters.P, _key.Parameters.G, _key.Parameters.L);

                return(new PrivateKeyInfo(
                           new AlgorithmIdentifier(_key.AlgorithmOid, p.ToAsn1Object()),
                           new DerInteger(_key.X),
                           attributes));
            }

            if (privateKey is RsaKeyParameters)
            {
                AlgorithmIdentifier algID = new AlgorithmIdentifier(
                    PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance);

                RsaPrivateKeyStructure keyStruct;
                if (privateKey is RsaPrivateCrtKeyParameters)
                {
                    RsaPrivateCrtKeyParameters _key = (RsaPrivateCrtKeyParameters)privateKey;

                    keyStruct = new RsaPrivateKeyStructure(
                        _key.Modulus,
                        _key.PublicExponent,
                        _key.Exponent,
                        _key.P,
                        _key.Q,
                        _key.DP,
                        _key.DQ,
                        _key.QInv);
                }
                else
                {
                    RsaKeyParameters _key = (RsaKeyParameters)privateKey;

                    keyStruct = new RsaPrivateKeyStructure(
                        _key.Modulus,
                        BigInteger.Zero,
                        _key.Exponent,
                        BigInteger.Zero,
                        BigInteger.Zero,
                        BigInteger.Zero,
                        BigInteger.Zero,
                        BigInteger.Zero);
                }

                return(new PrivateKeyInfo(algID, keyStruct.ToAsn1Object(), attributes));
            }

            if (privateKey is ECPrivateKeyParameters)
            {
                ECPrivateKeyParameters priv      = (ECPrivateKeyParameters)privateKey;
                DerBitString           publicKey = new DerBitString(ECKeyPairGenerator.GetCorrespondingPublicKey(priv).Q.GetEncoded(false));

                ECDomainParameters dp = priv.Parameters;
                int orderBitLength    = dp.N.BitLength;

                AlgorithmIdentifier   algID;
                ECPrivateKeyStructure ec;

                if (priv.AlgorithmName == "ECGOST3410")
                {
                    if (priv.PublicKeyParamSet == null)
                    {
                        throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set");
                    }

                    Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters(
                        priv.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet);

                    algID = new AlgorithmIdentifier(CryptoProObjectIdentifiers.GostR3410x2001, gostParams);

                    // TODO Do we need to pass any parameters here?
                    ec = new ECPrivateKeyStructure(orderBitLength, priv.D, publicKey, null);
                }
                else
                {
                    X962Parameters x962;
                    if (priv.PublicKeyParamSet == null)
                    {
                        X9ECParameters ecP = new X9ECParameters(dp.Curve, dp.G, dp.N, dp.H, dp.GetSeed());
                        x962 = new X962Parameters(ecP);
                    }
                    else
                    {
                        x962 = new X962Parameters(priv.PublicKeyParamSet);
                    }

                    ec = new ECPrivateKeyStructure(orderBitLength, priv.D, publicKey, x962);

                    algID = new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, x962);
                }

                return(new PrivateKeyInfo(algID, ec, attributes));
            }

            if (privateKey is Gost3410PrivateKeyParameters)
            {
                Gost3410PrivateKeyParameters _key = (Gost3410PrivateKeyParameters)privateKey;

                if (_key.PublicKeyParamSet == null)
                {
                    throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set");
                }

                byte[] keyEnc   = _key.X.ToByteArrayUnsigned();
                byte[] keyBytes = new byte[keyEnc.Length];

                for (int i = 0; i != keyBytes.Length; i++)
                {
                    keyBytes[i] = keyEnc[keyEnc.Length - 1 - i]; // must be little endian
                }

                Gost3410PublicKeyAlgParameters algParams = new Gost3410PublicKeyAlgParameters(
                    _key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet, null);

                AlgorithmIdentifier algID = new AlgorithmIdentifier(
                    CryptoProObjectIdentifiers.GostR3410x94,
                    algParams.ToAsn1Object());

                return(new PrivateKeyInfo(algID, new DerOctetString(keyBytes), attributes));
            }

            if (privateKey is X448PrivateKeyParameters)
            {
                X448PrivateKeyParameters key = (X448PrivateKeyParameters)privateKey;

                return(new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X448),
                                          new DerOctetString(key.GetEncoded()), attributes, key.GeneratePublicKey().GetEncoded()));
            }

            if (privateKey is X25519PrivateKeyParameters)
            {
                X25519PrivateKeyParameters key = (X25519PrivateKeyParameters)privateKey;

                return(new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519),
                                          new DerOctetString(key.GetEncoded()), attributes, key.GeneratePublicKey().GetEncoded()));
            }

            if (privateKey is Ed448PrivateKeyParameters)
            {
                Ed448PrivateKeyParameters key = (Ed448PrivateKeyParameters)privateKey;

                return(new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed448),
                                          new DerOctetString(key.GetEncoded()), attributes, key.GeneratePublicKey().GetEncoded()));
            }

            if (privateKey is Ed25519PrivateKeyParameters)
            {
                Ed25519PrivateKeyParameters key = (Ed25519PrivateKeyParameters)privateKey;

                return(new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519),
                                          new DerOctetString(key.GetEncoded()), attributes, key.GeneratePublicKey().GetEncoded()));
            }

            throw new ArgumentException("Class provided is not convertible: " + Platform.GetTypeName(privateKey));
        }
예제 #22
0
        private void DoEngineTestFp()
        {
            BigInteger SM2_ECC_P  = new BigInteger("8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3", 16);
            BigInteger SM2_ECC_A  = new BigInteger("787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498", 16);
            BigInteger SM2_ECC_B  = new BigInteger("63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A", 16);
            BigInteger SM2_ECC_N  = new BigInteger("8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7", 16);
            BigInteger SM2_ECC_H  = BigInteger.One;
            BigInteger SM2_ECC_GX = new BigInteger("421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D", 16);
            BigInteger SM2_ECC_GY = new BigInteger("0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2", 16);

            ECCurve curve = new FpCurve(SM2_ECC_P, SM2_ECC_A, SM2_ECC_B, SM2_ECC_N, SM2_ECC_H);

            ECPoint            g            = curve.CreatePoint(SM2_ECC_GX, SM2_ECC_GY);
            ECDomainParameters domainParams = new ECDomainParameters(curve, g, SM2_ECC_N);

            ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();

            ECKeyGenerationParameters aKeyGenParams = new ECKeyGenerationParameters(domainParams, new TestRandomBigInteger("1649AB77A00637BD5E2EFE283FBF353534AA7F7CB89463F208DDBC2920BB0DA0", 16));

            keyPairGenerator.Init(aKeyGenParams);

            AsymmetricCipherKeyPair aKp = keyPairGenerator.GenerateKeyPair();

            ECPublicKeyParameters  aPub  = (ECPublicKeyParameters)aKp.Public;
            ECPrivateKeyParameters aPriv = (ECPrivateKeyParameters)aKp.Private;

            SM2Engine sm2Engine = new SM2Engine();

            byte[] m = Strings.ToByteArray("encryption standard");

            sm2Engine.Init(true, new ParametersWithRandom(aPub, new TestRandomBigInteger("4C62EEFD6ECFC2B95B92FD6C3D9575148AFA17425546D49018E5388D49DD7B4F", 16)));

            byte[] enc = sm2Engine.ProcessBlock(m, 0, m.Length);

            IsTrue("enc wrong", Arrays.AreEqual(Hex.Decode(
                                                    "04245C26 FB68B1DD DDB12C4B 6BF9F2B6 D5FE60A3 83B0D18D 1C4144AB F17F6252" +
                                                    "E776CB92 64C2A7E8 8E52B199 03FDC473 78F605E3 6811F5C0 7423A24B 84400F01" +
                                                    "B8650053 A89B41C4 18B0C3AA D00D886C 00286467 9C3D7360 C30156FA B7C80A02" +
                                                    "76712DA9 D8094A63 4B766D3A 285E0748 0653426D"), enc));

            sm2Engine.Init(false, aPriv);

            byte[] dec = sm2Engine.ProcessBlock(enc, 0, enc.Length);

            IsTrue("dec wrong", Arrays.AreEqual(m, dec));

            enc[80] = (byte)(enc[80] + 1);

            try
            {
                sm2Engine.ProcessBlock(enc, 0, enc.Length);
                Fail("no exception");
            }
            catch (InvalidCipherTextException e)
            {
                IsTrue("wrong exception", "invalid cipher text".Equals(e.Message));
            }

            // long message
            sm2Engine = new SM2Engine();

            m = new byte[4097];
            for (int i = 0; i != m.Length; i++)
            {
                m[i] = (byte)i;
            }

            sm2Engine.Init(true, new ParametersWithRandom(aPub, new TestRandomBigInteger("4C62EEFD6ECFC2B95B92FD6C3D9575148AFA17425546D49018E5388D49DD7B4F", 16)));

            enc = sm2Engine.ProcessBlock(m, 0, m.Length);

            sm2Engine.Init(false, aPriv);

            dec = sm2Engine.ProcessBlock(enc, 0, enc.Length);

            IsTrue("dec wrong", Arrays.AreEqual(m, dec));
        }
예제 #23
0
        /// <summary>
        /// Make a new Alias Cert.  If refresh=false, a new DevID and Alias are created.  If refresh=true
        /// then just the Alias is created and re-certified using the stored DevID key.
        /// </summary>
        /// <param name="refresh"></param>
        /// <returns></returns>
        internal DeviceBundle MakeAliasCert(bool refresh, int fwidSeed)
        {
            DateTime now = DateTime.Now;

            byte[] fwid = Helpers.HashData(new byte[1] {
                (byte)fwidSeed
            }, 0, 1);

            const int keyStrength           = 256;
            CryptoApiRandomGenerator rg     = new CryptoApiRandomGenerator();
            SecureRandom             random = new SecureRandom(rg);
            KeyGenerationParameters  keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
            var keyPairGenerator = new ECKeyPairGenerator();

            keyPairGenerator.Init(keyGenerationParameters);

            AsymmetricCipherKeyPair devIdKey = null;

            if (refresh)
            {
                devIdKey = (AsymmetricCipherKeyPair)Helpers.ReadPemObject(ToPath(Program.DeviceIDPrivate));
            }
            else
            {
                devIdKey = keyPairGenerator.GenerateKeyPair();
            }

            // test - remove
            var oids = new List <Object>()
            {
                X509Name.UnstructuredName
            };
            var values = new List <Object>()
            {
                "ljkljljklkjlkjlkjlkjlkjlkjlkjlkjlkjljklkjlkjlkjlkjljk"
            };
            X509Name name = new X509Name(oids, values);



            AsymmetricCipherKeyPair aliasKey = keyPairGenerator.GenerateKeyPair();

            // make a string name based on DevID public.  Note that the authoritative information
            // is encoded in the RIoT-extension: this is just for quick-and-dirty device identification.
            var pubInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(devIdKey.Public);

            byte[] pubEncoded      = pubInfo.GetDerEncoded();
            var    pubHashed       = Helpers.HashData(pubEncoded, 0, pubEncoded.Length);
            var    shortNameBytes  = Helpers.CopyArray(pubHashed, 0, 8);
            var    shortNameString = Helpers.Hexify(shortNameBytes);

            X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
            var serialNumber = new byte[8];

            rg.NextBytes(serialNumber);
            serialNumber[0] &= 0x7F;
            certGen.SetSerialNumber(new BigInteger(serialNumber));
            // The important name-related stuff is encoded in the RIoT extension
            certGen.SetIssuerDN(new X509Name($"CN=[I]DevID:{shortNameString}, O=MSR_TEST, C=US"));
            // test REMOVE
            //certGen.SetSubjectDN(name);
            certGen.SetSubjectDN(new X509Name($"CN=[S]DevID:{shortNameString}, O=MSR_TEST, C=US"));
            certGen.SetNotBefore(now);
            certGen.SetNotAfter(now + new TimeSpan(365 * 10, 0, 0, 0, 0));
            certGen.SetPublicKey(aliasKey.Public);

            // Add the extensions (todo: not sure about KeyUsage.DigitalSiganture
            certGen.AddExtension(X509Extensions.ExtendedKeyUsage, true,
                                 ExtendedKeyUsage.GetInstance(new DerSequence(KeyPurposeID.IdKPClientAuth)));
            certGen.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.DigitalSignature));
            AddRIoTExtension(certGen, fwid, devIdKey);

            // sign it
            ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WITHECDSA", devIdKey.Private, random);
            var certificate = certGen.Generate(signatureFactory);
            // and return the bundle
            DeviceBundle bundle = new DeviceBundle
            {
                AliasCert      = certificate,
                DeviceIDPublic = devIdKey.Public,
                AliasKeyPair   = aliasKey
            };

            // Just the AliasCert
            Helpers.WritePEMObject(ToPath(Program.AliasCert), bundle.AliasCert);
            // The Alias Key Pair
            Helpers.WritePEMObject(ToPath(Program.AliasKey), bundle.AliasKeyPair);
            // The encoded DevID
            Helpers.WritePEMObject(ToPath(Program.DeviceIDPublic), bundle.DeviceIDPublic);
            // DeviceIDPrivate (just for the update demo)
            Helpers.WritePEMObject(ToPath(Program.DeviceIDPrivate), devIdKey.Private);

            return(bundle);
        }
예제 #24
0
        private void DoKeyExchangeTestF2m()
        {
            BigInteger SM2_ECC_A  = new BigInteger("00", 16);
            BigInteger SM2_ECC_B  = new BigInteger("E78BCD09746C202378A7E72B12BCE00266B9627ECB0B5A25367AD1AD4CC6242B", 16);
            BigInteger SM2_ECC_N  = new BigInteger("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC972CF7E6B6F900945B3C6A0CF6161D", 16);
            BigInteger SM2_ECC_H  = BigInteger.ValueOf(4);
            BigInteger SM2_ECC_GX = new BigInteger("00CDB9CA7F1E6B0441F658343F4B10297C0EF9B6491082400A62E7A7485735FADD", 16);
            BigInteger SM2_ECC_GY = new BigInteger("013DE74DA65951C4D76DC89220D5F7777A611B1C38BAE260B175951DC8060C2B3E", 16);

            ECCurve curve = new F2mCurve(257, 12, SM2_ECC_A, SM2_ECC_B, SM2_ECC_N, SM2_ECC_H);

            ECPoint            g            = curve.CreatePoint(SM2_ECC_GX, SM2_ECC_GY);
            ECDomainParameters domainParams = new ECDomainParameters(curve, g, SM2_ECC_N, SM2_ECC_H);

            ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();

            ECKeyGenerationParameters aKeyGenParams = new ECKeyGenerationParameters(domainParams, new TestRandomBigInteger("4813903D254F2C20A94BC5704238496954BB5279F861952EF2C5298E84D2CEAA", 16));

            keyPairGenerator.Init(aKeyGenParams);

            AsymmetricCipherKeyPair aKp = keyPairGenerator.GenerateKeyPair();

            ECPublicKeyParameters  aPub  = (ECPublicKeyParameters)aKp.Public;
            ECPrivateKeyParameters aPriv = (ECPrivateKeyParameters)aKp.Private;

            ECKeyGenerationParameters aeKeyGenParams = new ECKeyGenerationParameters(domainParams, new TestRandomBigInteger("54A3D6673FF3A6BD6B02EBB164C2A3AF6D4A4906229D9BFCE68CC366A2E64BA4", 16));

            keyPairGenerator.Init(aeKeyGenParams);

            AsymmetricCipherKeyPair aeKp = keyPairGenerator.GenerateKeyPair();

            ECPublicKeyParameters  aePub  = (ECPublicKeyParameters)aeKp.Public;
            ECPrivateKeyParameters aePriv = (ECPrivateKeyParameters)aeKp.Private;

            ECKeyGenerationParameters bKeyGenParams = new ECKeyGenerationParameters(domainParams, new TestRandomBigInteger("08F41BAE0922F47C212803FE681AD52B9BF28A35E1CD0EC273A2CF813E8FD1DC", 16));

            keyPairGenerator.Init(bKeyGenParams);

            AsymmetricCipherKeyPair bKp = keyPairGenerator.GenerateKeyPair();

            ECPublicKeyParameters  bPub  = (ECPublicKeyParameters)bKp.Public;
            ECPrivateKeyParameters bPriv = (ECPrivateKeyParameters)bKp.Private;

            ECKeyGenerationParameters beKeyGenParams = new ECKeyGenerationParameters(domainParams, new TestRandomBigInteger("1F21933387BEF781D0A8F7FD708C5AE0A56EE3F423DBC2FE5BDF6F068C53F7AD", 16));

            keyPairGenerator.Init(beKeyGenParams);

            AsymmetricCipherKeyPair beKp = keyPairGenerator.GenerateKeyPair();

            ECPublicKeyParameters  bePub  = (ECPublicKeyParameters)beKp.Public;
            ECPrivateKeyParameters bePriv = (ECPrivateKeyParameters)beKp.Private;

            SM2KeyExchange exch = new SM2KeyExchange();

            exch.Init(new ParametersWithID(new SM2KeyExchangePrivateParameters(true, aPriv, aePriv), Strings.ToByteArray("*****@*****.**")));

            byte[] k1 = exch.CalculateKey(128, new ParametersWithID(new SM2KeyExchangePublicParameters(bPub, bePub), Strings.ToByteArray("*****@*****.**")));

            // there appears to be typo for ZA in the draft
            //IsTrue("F2m key 1 wrong", Arrays.AreEqual(Hex.Decode("4E587E5C66634F22D973A7D98BF8BE23"), k1));
            IsTrue("F2m key 1 wrong", Arrays.AreEqual(Hex.Decode("8c2b03289aa7126555dc660cfc29fd74"), k1));

            exch = new SM2KeyExchange();

            exch.Init(new ParametersWithID(new SM2KeyExchangePrivateParameters(false, bPriv, bePriv), Strings.ToByteArray("*****@*****.**")));

            byte[] k2 = exch.CalculateKey(128, new ParametersWithID(new SM2KeyExchangePublicParameters(aPub, aePub), Strings.ToByteArray("*****@*****.**")));

            //IsTrue("F2m key 2 wrong", Arrays.AreEqual(Hex.Decode("4E587E5C66634F22D973A7D98BF8BE23"), k2));
            IsTrue("F2m key 2 wrong", Arrays.AreEqual(Hex.Decode("8c2b03289aa7126555dc660cfc29fd74"), k2));

            // with key confirmation
            exch = new SM2KeyExchange();

            exch.Init(new ParametersWithID(new SM2KeyExchangePrivateParameters(false, bPriv, bePriv), Strings.ToByteArray("*****@*****.**")));

            byte[][] vals2 = exch.CalculateKeyWithConfirmation(128, null, new ParametersWithID(new SM2KeyExchangePublicParameters(aPub, aePub), Strings.ToByteArray("*****@*****.**")));

            IsTrue("key 2 wrong", Arrays.AreEqual(Hex.Decode("8c2b03289aa7126555dc660cfc29fd74"), k2));

            IsTrue("conf a tag 2 wrong", Arrays.AreEqual(Hex.Decode("d8294c4c0f0ac180feac95e8a0d786638c9e915b9a684b2348809af03a0de2a5"), vals2[1]));
            IsTrue("conf b tag 2 wrong", Arrays.AreEqual(Hex.Decode("52089e706911b58fd5e7c7b2ab5cf32bb61e481ef1e114a1e33d99eec84b5a4f"), vals2[2]));

            exch = new SM2KeyExchange();

            exch.Init(new ParametersWithID(new SM2KeyExchangePrivateParameters(true, aPriv, aePriv), Strings.ToByteArray("*****@*****.**")));

            byte[][] vals1 = exch.CalculateKeyWithConfirmation(128, vals2[1], new ParametersWithID(new SM2KeyExchangePublicParameters(bPub, bePub), Strings.ToByteArray("*****@*****.**")));

            IsTrue("conf key 1 wrong", Arrays.AreEqual(Hex.Decode("8c2b03289aa7126555dc660cfc29fd74"), vals1[0]));
            IsTrue("conf tag 1 wrong", Arrays.AreEqual(Hex.Decode("52089e706911b58fd5e7c7b2ab5cf32bb61e481ef1e114a1e33d99eec84b5a4f"), vals1[1]));
        }
예제 #25
0
        private static CertBundle MakeCertInternal(
            string issuerName, string subjectName,
            bool isCA,
            AsymmetricCipherKeyPair signerKey = null,
            AsymmetricCipherKeyPair certKey   = null,
            int pathLengthConstraint          = 0)
        {
            const int keyStrength              = 256;
            CryptoApiRandomGenerator   rg      = new CryptoApiRandomGenerator();
            SecureRandom               random  = new SecureRandom(rg);
            X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();

            // make a new ECC key pair.  The pubKey will go in the cert.  The private key may or may
            // not be used for signing, depending on whether the caller provides a signing key.
            KeyGenerationParameters keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
            var keyPairGenerator = new ECKeyPairGenerator();

            keyPairGenerator.Init(keyGenerationParameters);
            AsymmetricCipherKeyPair newKey = keyPairGenerator.GenerateKeyPair();

            if (certKey != null)
            {
                newKey = certKey;
            }

            certGen.SetPublicKey(newKey.Public);
            BigInteger serialNumber = new BigInteger(new byte[] { 2, 3, 4 });

            certGen.SetSerialNumber(serialNumber);
            certGen.SetIssuerDN(new X509Name(issuerName));
            certGen.SetSubjectDN(new X509Name(subjectName));

            DateTime notBefore = DateTime.UtcNow.Date;
            DateTime notAfter  = notBefore + new TimeSpan(365, 0, 0, 0);

            certGen.SetNotBefore(notBefore);
            certGen.SetNotAfter(notAfter);

            if (pathLengthConstraint != 0)
            {
                // then we want it to be a CA.  Using this constructor sets CA true AND sets the path length
                certGen.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(pathLengthConstraint));
            }
            else
            {
                certGen.AddExtension(X509Extensions.ExtendedKeyUsage, true,
                                     ExtendedKeyUsage.GetInstance(new DerSequence(KeyPurposeID.IdKPServerAuth)));
            };

            // Sign the cert
            var signingKey = (signerKey != null) ? signerKey : newKey;
            ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WITHECDSA", signingKey.Private, random);

            var certificate = certGen.Generate(signatureFactory);

            // and return the bundle
            var bundle = new CertBundle()
            {
                Certificate = certificate, KeyPair = newKey
            };

            return(bundle);
        }
예제 #26
0
        private void DoKeyExchangeTestFp()
        {
            BigInteger SM2_ECC_P  = new BigInteger("8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3", 16);
            BigInteger SM2_ECC_A  = new BigInteger("787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498", 16);
            BigInteger SM2_ECC_B  = new BigInteger("63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A", 16);
            BigInteger SM2_ECC_N  = new BigInteger("8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7", 16);
            BigInteger SM2_ECC_H  = BigInteger.One;
            BigInteger SM2_ECC_GX = new BigInteger("421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D", 16);
            BigInteger SM2_ECC_GY = new BigInteger("0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2", 16);

            ECCurve curve = new FpCurve(SM2_ECC_P, SM2_ECC_A, SM2_ECC_B, SM2_ECC_N, SM2_ECC_H);

            ECPoint            g            = curve.CreatePoint(SM2_ECC_GX, SM2_ECC_GY);
            ECDomainParameters domainParams = new ECDomainParameters(curve, g, SM2_ECC_N);

            ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();

            ECKeyGenerationParameters aKeyGenParams = new ECKeyGenerationParameters(domainParams, new TestRandomBigInteger("6FCBA2EF9AE0AB902BC3BDE3FF915D44BA4CC78F88E2F8E7F8996D3B8CCEEDEE", 16));

            keyPairGenerator.Init(aKeyGenParams);

            AsymmetricCipherKeyPair aKp = keyPairGenerator.GenerateKeyPair();

            ECPublicKeyParameters  aPub  = (ECPublicKeyParameters)aKp.Public;
            ECPrivateKeyParameters aPriv = (ECPrivateKeyParameters)aKp.Private;

            ECKeyGenerationParameters aeKeyGenParams = new ECKeyGenerationParameters(domainParams, new TestRandomBigInteger("83A2C9C8B96E5AF70BD480B472409A9A327257F1EBB73F5B073354B248668563", 16));

            keyPairGenerator.Init(aeKeyGenParams);

            AsymmetricCipherKeyPair aeKp = keyPairGenerator.GenerateKeyPair();

            ECPublicKeyParameters  aePub  = (ECPublicKeyParameters)aeKp.Public;
            ECPrivateKeyParameters aePriv = (ECPrivateKeyParameters)aeKp.Private;

            ECKeyGenerationParameters bKeyGenParams = new ECKeyGenerationParameters(domainParams, new TestRandomBigInteger("5E35D7D3F3C54DBAC72E61819E730B019A84208CA3A35E4C2E353DFCCB2A3B53", 16));

            keyPairGenerator.Init(bKeyGenParams);

            AsymmetricCipherKeyPair bKp = keyPairGenerator.GenerateKeyPair();

            ECPublicKeyParameters  bPub  = (ECPublicKeyParameters)bKp.Public;
            ECPrivateKeyParameters bPriv = (ECPrivateKeyParameters)bKp.Private;

            ECKeyGenerationParameters beKeyGenParams = new ECKeyGenerationParameters(domainParams, new TestRandomBigInteger("33FE21940342161C55619C4A0C060293D543C80AF19748CE176D83477DE71C80", 16));

            keyPairGenerator.Init(beKeyGenParams);

            AsymmetricCipherKeyPair beKp = keyPairGenerator.GenerateKeyPair();

            ECPublicKeyParameters  bePub  = (ECPublicKeyParameters)beKp.Public;
            ECPrivateKeyParameters bePriv = (ECPrivateKeyParameters)beKp.Private;

            SM2KeyExchange exch = new SM2KeyExchange();

            exch.Init(new ParametersWithID(new SM2KeyExchangePrivateParameters(true, aPriv, aePriv), Strings.ToByteArray("*****@*****.**")));

            byte[] k1 = exch.CalculateKey(128, new ParametersWithID(new SM2KeyExchangePublicParameters(bPub, bePub), Strings.ToByteArray("*****@*****.**")));

            IsTrue("key 1 wrong", Arrays.AreEqual(Hex.Decode("55b0ac62a6b927ba23703832c853ded4"), k1));

            exch = new SM2KeyExchange();

            exch.Init(new ParametersWithID(new SM2KeyExchangePrivateParameters(false, bPriv, bePriv), Strings.ToByteArray("*****@*****.**")));

            byte[] k2 = exch.CalculateKey(128, new ParametersWithID(new SM2KeyExchangePublicParameters(aPub, aePub), Strings.ToByteArray("*****@*****.**")));

            IsTrue("key 2 wrong", Arrays.AreEqual(Hex.Decode("55b0ac62a6b927ba23703832c853ded4"), k2));

            // with key confirmation
            exch = new SM2KeyExchange();

            exch.Init(new ParametersWithID(new SM2KeyExchangePrivateParameters(false, bPriv, bePriv), Strings.ToByteArray("*****@*****.**")));

            byte[][] vals2 = exch.CalculateKeyWithConfirmation(128, null, new ParametersWithID(new SM2KeyExchangePublicParameters(aPub, aePub), Strings.ToByteArray("*****@*****.**")));

            IsTrue("key 2 wrong", Arrays.AreEqual(Hex.Decode("55b0ac62a6b927ba23703832c853ded4"), k2));

            IsTrue("conf a tag 2 wrong", Arrays.AreEqual(Hex.Decode("284C8F198F141B502E81250F1581C7E9EEB4CA6990F9E02DF388B45471F5BC5C"), vals2[1]));
            IsTrue("conf b tag 2 wrong", Arrays.AreEqual(Hex.Decode("23444DAF8ED7534366CB901C84B3BDBB63504F4065C1116C91A4C00697E6CF7A"), vals2[2]));

            exch = new SM2KeyExchange();

            exch.Init(new ParametersWithID(new SM2KeyExchangePrivateParameters(true, aPriv, aePriv), Strings.ToByteArray("*****@*****.**")));

            byte[][] vals1 = exch.CalculateKeyWithConfirmation(128, vals2[1], new ParametersWithID(new SM2KeyExchangePublicParameters(bPub, bePub), Strings.ToByteArray("*****@*****.**")));

            IsTrue("conf key 1 wrong", Arrays.AreEqual(Hex.Decode("55b0ac62a6b927ba23703832c853ded4"), vals1[0]));
            IsTrue("conf tag 1 wrong", Arrays.AreEqual(Hex.Decode("23444DAF8ED7534366CB901C84B3BDBB63504F4065C1116C91A4C00697E6CF7A"), vals1[1]));
        }
예제 #27
0
        /// <summary>
        ///   Creates a new signing key pair
        /// </summary>
        /// <param name="name">The name of the key or zone</param>
        /// <param name="recordClass">The record class of the DnsKeyRecord</param>
        /// <param name="timeToLive">The TTL in seconds to the DnsKeyRecord</param>
        /// <param name="flags">The Flags of the DnsKeyRecord</param>
        /// <param name="protocol">The protocol version</param>
        /// <param name="algorithm">The key algorithm</param>
        /// <param name="keyStrength">The key strength or 0 for default strength</param>
        /// <returns></returns>
        public static DnsKeyRecord CreateSigningKey(DomainName name, RecordClass recordClass, int timeToLive, DnsKeyFlags flags, byte protocol, DnsSecAlgorithm algorithm, int keyStrength = 0)
        {
            byte[] privateKey;
            byte[] publicKey;

            switch (algorithm)
            {
            case DnsSecAlgorithm.RsaSha1:
            case DnsSecAlgorithm.RsaSha1Nsec3Sha1:
            case DnsSecAlgorithm.RsaSha256:
            case DnsSecAlgorithm.RsaSha512:
                if (keyStrength == 0)
                {
                    keyStrength = (flags == (DnsKeyFlags.Zone | DnsKeyFlags.SecureEntryPoint)) ? 2048 : 1024;
                }

                RsaKeyPairGenerator rsaKeyGen = new RsaKeyPairGenerator();
                rsaKeyGen.Init(new KeyGenerationParameters(_secureRandom, keyStrength));
                var rsaKey = rsaKeyGen.GenerateKeyPair();
                privateKey = PrivateKeyInfoFactory.CreatePrivateKeyInfo(rsaKey.Private).GetDerEncoded();
                var rsaPublicKey = (RsaKeyParameters)rsaKey.Public;
                var rsaExponent  = rsaPublicKey.Exponent.ToByteArrayUnsigned();
                var rsaModulus   = rsaPublicKey.Modulus.ToByteArrayUnsigned();

                int offset = 1;
                if (rsaExponent.Length > 255)
                {
                    publicKey = new byte[3 + rsaExponent.Length + rsaModulus.Length];
                    DnsMessageBase.EncodeUShort(publicKey, ref offset, (ushort)publicKey.Length);
                }
                else
                {
                    publicKey    = new byte[1 + rsaExponent.Length + rsaModulus.Length];
                    publicKey[0] = (byte)rsaExponent.Length;
                }
                DnsMessageBase.EncodeByteArray(publicKey, ref offset, rsaExponent);
                DnsMessageBase.EncodeByteArray(publicKey, ref offset, rsaModulus);
                break;

            case DnsSecAlgorithm.Dsa:
            case DnsSecAlgorithm.DsaNsec3Sha1:
                if (keyStrength == 0)
                {
                    keyStrength = 1024;
                }

                DsaParametersGenerator dsaParamsGen = new DsaParametersGenerator();
                dsaParamsGen.Init(keyStrength, 12, _secureRandom);
                DsaKeyPairGenerator dsaKeyGen = new DsaKeyPairGenerator();
                dsaKeyGen.Init(new DsaKeyGenerationParameters(_secureRandom, dsaParamsGen.GenerateParameters()));
                var dsaKey = dsaKeyGen.GenerateKeyPair();
                privateKey = PrivateKeyInfoFactory.CreatePrivateKeyInfo(dsaKey.Private).GetDerEncoded();
                var dsaPublicKey = (DsaPublicKeyParameters)dsaKey.Public;

                var dsaY = dsaPublicKey.Y.ToByteArrayUnsigned();
                var dsaP = dsaPublicKey.Parameters.P.ToByteArrayUnsigned();
                var dsaQ = dsaPublicKey.Parameters.Q.ToByteArrayUnsigned();
                var dsaG = dsaPublicKey.Parameters.G.ToByteArrayUnsigned();
                var dsaT = (byte)((dsaY.Length - 64) / 8);

                publicKey    = new byte[21 + 3 * dsaY.Length];
                publicKey[0] = dsaT;
                dsaQ.CopyTo(publicKey, 1);
                dsaP.CopyTo(publicKey, 21);
                dsaG.CopyTo(publicKey, 21 + dsaY.Length);
                dsaY.CopyTo(publicKey, 21 + 2 * dsaY.Length);
                break;

            case DnsSecAlgorithm.EccGost:
                ECDomainParameters gostEcDomainParameters = ECGost3410NamedCurves.GetByOid(CryptoProObjectIdentifiers.GostR3410x2001CryptoProA);

                var gostKeyGen = new ECKeyPairGenerator();
                gostKeyGen.Init(new ECKeyGenerationParameters(gostEcDomainParameters, _secureRandom));

                var gostKey = gostKeyGen.GenerateKeyPair();
                privateKey = PrivateKeyInfoFactory.CreatePrivateKeyInfo(gostKey.Private).GetDerEncoded();
                var gostPublicKey = (ECPublicKeyParameters)gostKey.Public;

                publicKey = new byte[64];

                gostPublicKey.Q.X.ToBigInteger().ToByteArrayUnsigned().CopyTo(publicKey, 32);
                gostPublicKey.Q.Y.ToBigInteger().ToByteArrayUnsigned().CopyTo(publicKey, 0);

                publicKey = publicKey.Reverse().ToArray();
                break;

            case DnsSecAlgorithm.EcDsaP256Sha256:
            case DnsSecAlgorithm.EcDsaP384Sha384:
                int            ecDsaDigestSize;
                X9ECParameters ecDsaCurveParameter;

                if (algorithm == DnsSecAlgorithm.EcDsaP256Sha256)
                {
                    ecDsaDigestSize     = new Sha256Digest().GetDigestSize();
                    ecDsaCurveParameter = NistNamedCurves.GetByOid(SecObjectIdentifiers.SecP256r1);
                }
                else
                {
                    ecDsaDigestSize     = new Sha384Digest().GetDigestSize();
                    ecDsaCurveParameter = NistNamedCurves.GetByOid(SecObjectIdentifiers.SecP384r1);
                }

                ECDomainParameters ecDsaP384EcDomainParameters = new ECDomainParameters(
                    ecDsaCurveParameter.Curve,
                    ecDsaCurveParameter.G,
                    ecDsaCurveParameter.N,
                    ecDsaCurveParameter.H,
                    ecDsaCurveParameter.GetSeed());

                var ecDsaKeyGen = new ECKeyPairGenerator();
                ecDsaKeyGen.Init(new ECKeyGenerationParameters(ecDsaP384EcDomainParameters, _secureRandom));

                var ecDsaKey = ecDsaKeyGen.GenerateKeyPair();
                privateKey = PrivateKeyInfoFactory.CreatePrivateKeyInfo(ecDsaKey.Private).GetDerEncoded();
                var ecDsaPublicKey = (ECPublicKeyParameters)ecDsaKey.Public;

                publicKey = new byte[ecDsaDigestSize * 2];

                ecDsaPublicKey.Q.X.ToBigInteger().ToByteArrayUnsigned().CopyTo(publicKey, 0);
                ecDsaPublicKey.Q.Y.ToBigInteger().ToByteArrayUnsigned().CopyTo(publicKey, ecDsaDigestSize);
                break;

            default:
                throw new NotSupportedException();
            }

            return(new DnsKeyRecord(name, recordClass, timeToLive, flags, protocol, algorithm, publicKey, privateKey));
        }
        public SimpleTestResult EncodeRecodePublicKey()
        {
            DerObjectIdentifier       oid          = ECGost3410NamedCurves.GetOid("Tc26-Gost-3410-12-512-paramSetA");
            ECNamedDomainParameters   ecp          = new ECNamedDomainParameters(oid, ECGost3410NamedCurves.GetByOidX9(oid));
            ECGost3410Parameters      gostParams   = new ECGost3410Parameters(ecp, oid, RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512, null);
            ECKeyGenerationParameters paramameters = new ECKeyGenerationParameters(gostParams, new SecureRandom());
            ECKeyPairGenerator        engine       = new ECKeyPairGenerator();

            engine.Init(paramameters);
            AsymmetricCipherKeyPair pair = engine.GenerateKeyPair();

            ECPublicKeyParameters generatedKeyParameters = (ECPublicKeyParameters)pair.Public;
            ECPublicKeyParameters keyParameters          = generatedKeyParameters;

            //
            // Continuously encode/decode the key and check for loss of information.
            //
            for (int t = 0; t < 3; t++)
            {
                SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyParameters);
                keyParameters = (ECPublicKeyParameters)PublicKeyFactory.CreateKey(info);

                {
                    // Specifically cast and test gost parameters.
                    ECGost3410Parameters gParam = (ECGost3410Parameters)generatedKeyParameters.Parameters;
                    ECGost3410Parameters rParam = (ECGost3410Parameters)keyParameters.Parameters;

                    bool ok = SafeEquals(gParam.DigestParamSet, rParam.DigestParamSet) &&
                              SafeEquals(gParam.EncryptionParamSet, rParam.EncryptionParamSet) &&
                              SafeEquals(gParam.PublicKeyParamSet, rParam.PublicKeyParamSet);

                    if (!ok)
                    {
                        return(new SimpleTestResult(false, "GOST parameters does not match"));
                    }
                }

                if (!((ECGost3410Parameters)keyParameters.Parameters).Name.Equals(
                        ((ECGost3410Parameters)generatedKeyParameters.Parameters).Name))
                {
                    return(new SimpleTestResult(false, "Name does not match"));
                }

                if (keyParameters.IsPrivate != generatedKeyParameters.IsPrivate)
                {
                    return(new SimpleTestResult(false, "isPrivate does not match"));
                }

                if (!Arrays.AreEqual(keyParameters.Q.GetEncoded(true), generatedKeyParameters.Q.GetEncoded(true)))
                {
                    return(new SimpleTestResult(false, "Q does not match"));
                }

                if (!keyParameters.Parameters.Curve.Equals(generatedKeyParameters.Parameters.Curve))
                {
                    return(new SimpleTestResult(false, "Curve does not match"));
                }

                if (!Arrays.AreEqual(
                        keyParameters.Parameters.G.GetEncoded(true),
                        generatedKeyParameters.Parameters.G.GetEncoded(true)))
                {
                    return(new SimpleTestResult(false, "G does not match"));
                }

                if (!keyParameters.Parameters.H.Equals(generatedKeyParameters.Parameters.H))
                {
                    return(new SimpleTestResult(false, "H does not match"));
                }

                if (!keyParameters.Parameters.HInv.Equals(generatedKeyParameters.Parameters.HInv))
                {
                    return(new SimpleTestResult(false, "Hinv does not match"));
                }

                if (!keyParameters.Parameters.N.Equals(generatedKeyParameters.Parameters.N))
                {
                    return(new SimpleTestResult(false, "N does not match"));
                }

                if (!Arrays.AreEqual(keyParameters.Parameters.GetSeed(), generatedKeyParameters.Parameters.GetSeed()))
                {
                    return(new SimpleTestResult(false, "Seed does not match"));
                }
            }

            return(new SimpleTestResult(true, null));
        }
예제 #29
0
        /**
         * Read a Key Pair
         */
        private object ReadPrivateKey(PemObject pemObject)
        {
            //
            // extract the key
            //
            Debug.Assert(Platform.EndsWith(pemObject.Type, "PRIVATE KEY"));

            string type = pemObject.Type.Substring(0, pemObject.Type.Length - "PRIVATE KEY".Length).Trim();

            byte[] keyBytes = pemObject.Content;

            IDictionary fields = Platform.CreateHashtable();

            foreach (PemHeader header in pemObject.Headers)
            {
                fields[header.Name] = header.Value;
            }

            string procType = (string)fields["Proc-Type"];

            if (procType == "4,ENCRYPTED")
            {
                if (pFinder == null)
                {
                    throw new PasswordException("No password finder specified, but a password is required");
                }

                char[] password = pFinder.GetPassword();

                if (password == null)
                {
                    throw new PasswordException("Password is null, but a password is required");
                }

                string   dekInfo = (string)fields["DEK-Info"];
                string[] tknz    = dekInfo.Split(',');

                string dekAlgName = tknz[0].Trim();
                byte[] iv         = Hex.Decode(tknz[1].Trim());

                keyBytes = PemUtilities.Crypt(false, keyBytes, password, dekAlgName, iv);
            }

            try
            {
                AsymmetricKeyParameter pubSpec, privSpec;
                Asn1Sequence           seq = Asn1Sequence.GetInstance(keyBytes);

                switch (type)
                {
                case "RSA":
                {
                    if (seq.Count != 9)
                    {
                        throw new PemException("malformed sequence in RSA private key");
                    }

                    RsaPrivateKeyStructure rsa = RsaPrivateKeyStructure.GetInstance(seq);

                    pubSpec  = new RsaKeyParameters(false, rsa.Modulus, rsa.PublicExponent);
                    privSpec = new RsaPrivateCrtKeyParameters(
                        rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent,
                        rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2,
                        rsa.Coefficient);

                    break;
                }

                case "DSA":
                {
                    if (seq.Count != 6)
                    {
                        throw new PemException("malformed sequence in DSA private key");
                    }

                    // TODO Create an ASN1 object somewhere for this?
                    //DerInteger v = (DerInteger)seq[0];
                    DerInteger p = (DerInteger)seq[1];
                    DerInteger q = (DerInteger)seq[2];
                    DerInteger g = (DerInteger)seq[3];
                    DerInteger y = (DerInteger)seq[4];
                    DerInteger x = (DerInteger)seq[5];

                    DsaParameters parameters = new DsaParameters(p.Value, q.Value, g.Value);

                    privSpec = new DsaPrivateKeyParameters(x.Value, parameters);
                    pubSpec  = new DsaPublicKeyParameters(y.Value, parameters);

                    break;
                }

                case "EC":
                {
                    ECPrivateKeyStructure pKey  = ECPrivateKeyStructure.GetInstance(seq);
                    AlgorithmIdentifier   algId = new AlgorithmIdentifier(
                        X9ObjectIdentifiers.IdECPublicKey, pKey.GetParameters());

                    PrivateKeyInfo privInfo = new PrivateKeyInfo(algId, pKey.ToAsn1Object());

                    // TODO Are the keys returned here ECDSA, as Java version forces?
                    privSpec = PrivateKeyFactory.CreateKey(privInfo);

                    DerBitString pubKey = pKey.GetPublicKey();
                    if (pubKey != null)
                    {
                        SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, pubKey.GetBytes());

                        // TODO Are the keys returned here ECDSA, as Java version forces?
                        pubSpec = PublicKeyFactory.CreateKey(pubInfo);
                    }
                    else
                    {
                        pubSpec = ECKeyPairGenerator.GetCorrespondingPublicKey(
                            (ECPrivateKeyParameters)privSpec);
                    }

                    break;
                }

                case "ENCRYPTED":
                {
                    char[] password = pFinder.GetPassword();

                    if (password == null)
                    {
                        throw new PasswordException("Password is null, but a password is required");
                    }

                    return(PrivateKeyFactory.DecryptKey(password, EncryptedPrivateKeyInfo.GetInstance(seq)));
                }

                case "":
                {
                    return(PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(seq)));
                }

                default:
                    throw new ArgumentException("Unknown key type: " + type, "type");
                }

                return(new AsymmetricCipherKeyPair(pubSpec, privSpec));
            }
            catch (IOException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PemException(
                          "problem creating " + type + " private key: " + e.ToString());
            }
        }
예제 #30
0
        public static AsymmetricKeyParameter CreateKey(
            SubjectPublicKeyInfo keyInfo)
        {
            var algID  = keyInfo.AlgorithmID;
            var algOid = algID.Algorithm;

            // TODO See RSAUtil.isRsaOid in Java build
            if (algOid.Equals(PkcsObjectIdentifiers.RsaEncryption) ||
                algOid.Equals(X509ObjectIdentifiers.IdEARsa) ||
                algOid.Equals(PkcsObjectIdentifiers.IdRsassaPss) ||
                algOid.Equals(PkcsObjectIdentifiers.IdRsaesOaep))
            {
                var pubKey = RsaPublicKeyStructure.GetInstance(
                    keyInfo.GetPublicKey());

                return(new RsaKeyParameters(false, pubKey.Modulus, pubKey.PublicExponent));
            }

            if (algOid.Equals(X9ObjectIdentifiers.DHPublicNumber))
            {
                var seq = Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object());

                var dhPublicKey = DHPublicKey.GetInstance(keyInfo.GetPublicKey());

                var y = dhPublicKey.Y.Value;

                if (IsPkcsDHParam(seq))
                {
                    return(ReadPkcsDHParam(algOid, y, seq));
                }

                var dhParams = DHDomainParameters.GetInstance(seq);

                var p = dhParams.P.Value;
                var g = dhParams.G.Value;
                var q = dhParams.Q.Value;

                BigInteger j = null;
                if (dhParams.J != null)
                {
                    j = dhParams.J.Value;
                }

                DHValidationParameters validation = null;
                var dhValidationParms             = dhParams.ValidationParms;
                if (dhValidationParms != null)
                {
                    var seed        = dhValidationParms.Seed.GetBytes();
                    var pgenCounter = dhValidationParms.PgenCounter.Value;

                    // TODO Check pgenCounter size?

                    validation = new DHValidationParameters(seed, pgenCounter.IntValue);
                }

                return(new DHPublicKeyParameters(y, new DHParameters(p, g, q, j, validation)));
            }

            if (algOid.Equals(PkcsObjectIdentifiers.DhKeyAgreement))
            {
                var seq = Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object());

                var derY = (DerInteger)keyInfo.GetPublicKey();

                return(ReadPkcsDHParam(algOid, derY.Value, seq));
            }

            if (algOid.Equals(OiwObjectIdentifiers.ElGamalAlgorithm))
            {
                var para = new ElGamalParameter(
                    Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
                var derY = (DerInteger)keyInfo.GetPublicKey();

                return(new ElGamalPublicKeyParameters(
                           derY.Value,
                           new ElGamalParameters(para.P, para.G)));
            }

            if (algOid.Equals(X9ObjectIdentifiers.IdDsa) ||
                algOid.Equals(OiwObjectIdentifiers.DsaWithSha1))
            {
                var derY = (DerInteger)keyInfo.GetPublicKey();
                var ae   = algID.Parameters;

                DsaParameters parameters = null;
                if (ae != null)
                {
                    var para = DsaParameter.GetInstance(ae.ToAsn1Object());
                    parameters = new DsaParameters(para.P, para.Q, para.G);
                }

                return(new DsaPublicKeyParameters(derY.Value, parameters));
            }

            if (algOid.Equals(X9ObjectIdentifiers.IdECPublicKey))
            {
                var para = new X962Parameters(algID.Parameters.ToAsn1Object());

                X9ECParameters x9;
                if (para.IsNamedCurve)
                {
                    x9 = ECKeyPairGenerator.FindECCurveByOid((DerObjectIdentifier)para.Parameters);
                }
                else
                {
                    x9 = new X9ECParameters((Asn1Sequence)para.Parameters);
                }

                Asn1OctetString key  = new DerOctetString(keyInfo.PublicKeyData.GetBytes());
                var             derQ = new X9ECPoint(x9.Curve, key);
                var             q    = derQ.Point;

                if (para.IsNamedCurve)
                {
                    return(new ECPublicKeyParameters("EC", q, (DerObjectIdentifier)para.Parameters));
                }

                var dParams = new ECDomainParameters(x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed());
                return(new ECPublicKeyParameters(q, dParams));
            }

            if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001))
            {
                var gostParams = new Gost3410PublicKeyAlgParameters(
                    (Asn1Sequence)algID.Parameters);

                Asn1OctetString key;
                try
                {
                    key = (Asn1OctetString)keyInfo.GetPublicKey();
                }
                catch (IOException)
                {
                    throw new ArgumentException("invalid info structure in GOST3410 public key");
                }

                var keyEnc = key.GetOctets();
                var x      = new byte[32];
                var y      = new byte[32];

                for (var i = 0; i != y.Length; i++)
                {
                    x[i] = keyEnc[32 - 1 - i];
                }

                for (var i = 0; i != x.Length; i++)
                {
                    y[i] = keyEnc[64 - 1 - i];
                }

                var ecP = ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet);

                if (ecP == null)
                {
                    return(null);
                }

                var q = ecP.Curve.CreatePoint(new BigInteger(1, x), new BigInteger(1, y));

                return(new ECPublicKeyParameters("ECGOST3410", q, gostParams.PublicKeyParamSet));
            }

            if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x94))
            {
                var algParams = new Gost3410PublicKeyAlgParameters(
                    (Asn1Sequence)algID.Parameters);

                DerOctetString derY;
                try
                {
                    derY = (DerOctetString)keyInfo.GetPublicKey();
                }
                catch (IOException)
                {
                    throw new ArgumentException("invalid info structure in GOST3410 public key");
                }

                var keyEnc   = derY.GetOctets();
                var keyBytes = new byte[keyEnc.Length];

                for (var i = 0; i != keyEnc.Length; i++)
                {
                    keyBytes[i] = keyEnc[keyEnc.Length - 1 - i]; // was little endian
                }

                var y = new BigInteger(1, keyBytes);

                return(new Gost3410PublicKeyParameters(y, algParams.PublicKeyParamSet));
            }
            if (algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256) ||
                algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512))
            {
                var algParams = new Gost3410PublicKeyAlgParameters(
                    (Asn1Sequence)algID.Parameters);

                Asn1OctetString key;
                try
                {
                    key = (Asn1OctetString)keyInfo.GetPublicKey();
                }
                catch (IOException)
                {
                    throw new ArgumentException("invalid info structure in GOST3410-2012 public key");
                }

                var keyEnc = key.GetOctets();

                var fieldSize = 32;
                if (algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512))
                {
                    fieldSize = 64;
                }

                var keySize = 2 * fieldSize;

                var x9Encoding = new byte[1 + keySize];
                x9Encoding[0] = 0x04;
                for (var i = 1; i <= fieldSize; ++i)
                {
                    x9Encoding[i]             = keyEnc[fieldSize - i];
                    x9Encoding[i + fieldSize] = keyEnc[keySize - i];
                }

                var ecP = ECGost3410NamedCurves.GetByOid(algParams.PublicKeyParamSet);

                if (ecP == null)
                {
                    return(null);
                }

                return(new ECPublicKeyParameters(ecP.Curve.DecodePoint(x9Encoding), ecP));
            }

            throw new SecurityUtilityException("algorithm identifier in key not recognised: " + algOid);
        }