Beispiel #1
0
        /**
         * sm2验签
         * @param userId ID值,若无约定,使用默认:1234567812345678
         * @param publicKey 公钥,二进制数据
         * @param sourceData 待验签数据
         * @param signData 签名值
         * @return 返回是否成功
         */
        public static Boolean VerifySign(byte[] userId, byte[] publicKey, byte[] sourceData, byte[] signData)
        {
            if (publicKey.Length == 64)
            {
                byte[] tmp = new byte[65];
                Buffer.BlockCopy(publicKey, 0, tmp, 1, publicKey.Length);
                tmp[0]    = 0x04;
                publicKey = tmp;
            }

            X9ECParameters        sm2p256v1        = GMNamedCurves.GetByName("sm2p256v1");
            ECDomainParameters    parameters       = new ECDomainParameters(sm2p256v1.Curve, sm2p256v1.G, sm2p256v1.N);
            ECPublicKeyParameters pubKeyParameters = new ECPublicKeyParameters(sm2p256v1.Curve.DecodePoint(publicKey), parameters);
            SM2Signer             signer           = new SM2Signer();
            ICipherParameters     param;

            if (userId != null)
            {
                param = new ParametersWithID(pubKeyParameters, userId);
            }
            else
            {
                param = pubKeyParameters;
            }
            signer.Init(false, param);
            signer.BlockUpdate(sourceData, 0, sourceData.Length);
            return(signer.VerifySignature(signData));
        }
Beispiel #2
0
        /**
         * return the object identifier signified by the passed in name. Null
         * if there is no object identifier associated with name.
         *
         * @return the object identifier associated with name, if present.
         */
        public static DerObjectIdentifier GetOid(string name)
        {
            DerObjectIdentifier oid = X962NamedCurves.GetOid(name);

            if (oid == null)
            {
                oid = SecNamedCurves.GetOid(name);
            }
            if (oid == null)
            {
                oid = NistNamedCurves.GetOid(name);
            }
            if (oid == null)
            {
                oid = TeleTrusTNamedCurves.GetOid(name);
            }
            if (oid == null)
            {
                oid = AnssiNamedCurves.GetOid(name);
            }
            if (oid == null)
            {
                oid = ECGost3410NamedCurves.GetOid(name);
            }
            if (oid == null)
            {
                oid = GMNamedCurves.GetOid(name);
            }
            return(oid);
        }
Beispiel #3
0
        /**
         * return a X9ECParameters object representing the passed in named
         * curve.
         *
         * @param oid the object id of the curve requested
         * @return an X9ECParameters object or null if the curve is not available.
         */
        public static X9ECParameters GetByOid(DerObjectIdentifier oid)
        {
            X9ECParameters ecP = X962NamedCurves.GetByOid(oid);

            if (ecP == null)
            {
                ecP = SecNamedCurves.GetByOid(oid);
            }

            // NOTE: All the NIST curves are currently from SEC, so no point in redundant OID lookup

            if (ecP == null)
            {
                ecP = TeleTrusTNamedCurves.GetByOid(oid);
            }
            if (ecP == null)
            {
                ecP = AnssiNamedCurves.GetByOid(oid);
            }
            if (ecP == null)
            {
                ecP = FromDomainParameters(ECGost3410NamedCurves.GetByOid(oid));
            }
            if (ecP == null)
            {
                ecP = GMNamedCurves.GetByOid(oid);
            }
            return(ecP);
        }
Beispiel #4
0
        public static string GetName(DerObjectIdentifier oid)
        {
            string name = X962NamedCurves.GetName(oid);

            if (name == null)
            {
                name = SecNamedCurves.GetName(oid);
            }
            if (name == null)
            {
                name = NistNamedCurves.GetName(oid);
            }
            if (name == null)
            {
                name = TeleTrusTNamedCurves.GetName(oid);
            }
            if (name == null)
            {
                name = AnssiNamedCurves.GetName(oid);
            }
            if (name == null)
            {
                name = ECGost3410NamedCurves.GetName(oid);
            }
            if (name == null)
            {
                name = GMNamedCurves.GetName(oid);
            }
            return(name);
        }
Beispiel #5
0
        /**
         * return a X9ECParameters object representing the passed in named
         * curve. The routine returns null if the curve is not present.
         *
         * @param name the name of the curve requested
         * @return an X9ECParameters object or null if the curve is not available.
         */
        public static X9ECParameters GetByName(string name)
        {
            X9ECParameters ecP = X962NamedCurves.GetByName(name);

            if (ecP == null)
            {
                ecP = SecNamedCurves.GetByName(name);
            }
            if (ecP == null)
            {
                ecP = NistNamedCurves.GetByName(name);
            }
            if (ecP == null)
            {
                ecP = TeleTrusTNamedCurves.GetByName(name);
            }
            if (ecP == null)
            {
                ecP = AnssiNamedCurves.GetByName(name);
            }
            if (ecP == null)
            {
                ecP = FromDomainParameters(ECGost3410NamedCurves.GetByName(name));
            }
            if (ecP == null)
            {
                ecP = GMNamedCurves.GetByName(name);
            }
            return(ecP);
        }
Beispiel #6
0
        /// <summary>
        /// 验证签名
        /// </summary>
        /// <param name="publicKey">公钥</param>
        /// <param name="content">待签名内容</param>
        /// <param name="sign">签名值</param>
        /// <returns></returns>
        public static bool Verify(string publicKey, string content, string sign)
        {
            //待签名内容
            byte[] message  = Hex.Decode(content);
            byte[] signData = Hex.Decode(sign);

            // 获取一条SM2曲线参数
            X9ECParameters sm2EcParameters = GMNamedCurves.GetByName("sm2p256v1");
            // 构造domain参数
            ECDomainParameters domainParameters = new ECDomainParameters(sm2EcParameters.Curve, sm2EcParameters.G, sm2EcParameters.N);
            //提取公钥点
            ECPoint pukPoint = sm2EcParameters.Curve.DecodePoint(Hex.Decode(publicKey));
            // 公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥, 04的时候,可以去掉前面的04
            ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(pukPoint, domainParameters);

            //创建签名实例
            SM2Signer        sm2Signer        = new SM2Signer();
            ParametersWithID parametersWithId = new ParametersWithID(publicKeyParameters, Strings.ToByteArray("1234567812345678"));

            sm2Signer.Init(false, parametersWithId);
            //sm2Signer.BlockUpdate();


            //验证签名结果
            bool verify = sm2Signer.VerifySignature(message);

            return(verify);
        }
Beispiel #7
0
        /// <summary>
        /// 密钥对生成
        /// </summary>
        /// <param name="pubkey"></param>
        /// <param name="privkey"></param>
        public void GenerateKey(out byte[] pubkey, out byte[] privkey)
        {
            var g = new ECKeyPairGenerator();

            g.Init(new ECKeyGenerationParameters(new ECDomainParameters(GMNamedCurves.GetByName("SM2P256V1")), new SecureRandom()));
            var k = g.GenerateKeyPair();

            pubkey  = ((ECPublicKeyParameters)k.Public).Q.GetEncoded(false);
            privkey = ((ECPrivateKeyParameters)k.Private).D.ToByteArray();
        }
Beispiel #8
0
        /// <summary>
        /// Generate key pair.
        /// </summary>
        /// <returns></returns>
        public override AsymmetricCipherKeyPair GenerateKeyPair()
        {
            X9ECParameters                    parameters2 = GMNamedCurves.GetByOid(GMObjectIdentifiers.sm2p256v1);
            ECDomainParameters                parameters3 = new ECDomainParameters(parameters2);
            KeyGenerationParameters           parameters  = new ECKeyGenerationParameters(parameters3, Common.ThreadSecureRandom.Value);
            IAsymmetricCipherKeyPairGenerator generator   = new ECKeyPairGenerator();

            generator.Init(parameters);
            return(generator.GenerateKeyPair());
        }
Beispiel #9
0
        /**
         * sm2加密
         *
         */
        public static byte[] Encrypt(byte[] pubkey, byte[] srcData)
        {
            X9ECParameters        sm2p256v1        = GMNamedCurves.GetByName("sm2p256v1");
            SecureRandom          random           = new SecureRandom();
            ECDomainParameters    parameters       = new ECDomainParameters(sm2p256v1.Curve, sm2p256v1.G, sm2p256v1.N);
            ECPublicKeyParameters pubKeyParameters = new ECPublicKeyParameters(sm2p256v1.Curve.DecodePoint(pubkey), parameters);
            SM2Engine             engine           = new SM2Engine();
            ParametersWithRandom  pwr = new ParametersWithRandom(pubKeyParameters, new SecureRandom());

            engine.Init(true, pwr);
            return(encodeSM2CipherToDER(engine.ProcessBlock(srcData, 0, srcData.Length)));
        }
Beispiel #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="c1c3c2"></param>
        /// <returns></returns>
        public static byte[] C132ToC123(byte[] c1c3c2)
        {
            var gn    = GMNamedCurves.GetByName("SM2P256V1");
            int c1Len = (gn.Curve.FieldSize + 7) / 8 * 2 + 1;
            int c3Len = 32; //new SM3Digest().getDigestSize();

            byte[] result = new byte[c1c3c2.Length];
            Array.Copy(c1c3c2, 0, result, 0, c1Len);                                         //c1: 0->65
            Array.Copy(c1c3c2, c1Len + c3Len, result, c1Len, c1c3c2.Length - c1Len - c3Len); //c2
            Array.Copy(c1c3c2, c1Len, result, c1c3c2.Length - c3Len, c3Len);                 //c3
            return(result);
        }
Beispiel #11
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="c1c2c3"></param>
        /// <returns></returns>
        public static byte[] C123ToC132(byte[] c1c2c3)
        {
            var gn    = GMNamedCurves.GetByName("SM2P256V1");
            int c1Len = (gn.Curve.FieldSize + 7) / 8 * 2 + 1; //sm2p256v1的这个固定65。可看GMNamedCurves、ECCurve代码。
            int c3Len = 32;                                   //new SM3Digest().getDigestSize();

            byte[] result = new byte[c1c2c3.Length];
            Array.Copy(c1c2c3, 0, result, 0, c1Len);                                         //c1
            Array.Copy(c1c2c3, c1c2c3.Length - c3Len, result, c1Len, c3Len);                 //c3
            Array.Copy(c1c2c3, c1Len, result, c1Len + c3Len, c1c2c3.Length - c1Len - c3Len); //c2
            return(result);
        }
Beispiel #12
0
        /**
         * sm2解密
         */
        public static byte[] Decrypt(byte[] privkey, byte[] srcData)
        {
            X9ECParameters     sm2p256v1  = GMNamedCurves.GetByName("sm2p256v1");
            SecureRandom       random     = new SecureRandom();
            ECDomainParameters parameters = new ECDomainParameters(sm2p256v1.Curve, sm2p256v1.G, sm2p256v1.N);

            ECPrivateKeyParameters priKeyParameters = new ECPrivateKeyParameters(new BigInteger(1, privkey), parameters);
            SM2Engine            engine             = new SM2Engine();
            ParametersWithRandom pwr = new ParametersWithRandom(priKeyParameters, new SecureRandom());

            engine.Init(false, priKeyParameters);
            byte[] c1c2c3 = decodeDERSM2Cipher(srcData);
            return(engine.ProcessBlock(c1c2c3, 0, c1c2c3.Length));
        }
Beispiel #13
0
        /// <summary>
        /// 生成SM2公私钥对
        /// </summary>
        /// <returns></returns>
        private static AsymmetricCipherKeyPair CreateKeyPairInternal()
        {
            //获取一条SM2曲线参数
            X9ECParameters sm2EcParameters = GMNamedCurves.GetByName("sm2p256v1");

            //构造domain参数
            ECDomainParameters domainParameters = new ECDomainParameters(sm2EcParameters.Curve, sm2EcParameters.G, sm2EcParameters.N);

            //1.创建密钥生成器
            ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();

            //2.初始化生成器,带上随机数
            keyPairGenerator.Init(new ECKeyGenerationParameters(domainParameters, SecureRandom.GetInstance("SHA1PRNG")));

            //3.生成密钥对
            AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.GenerateKeyPair();

            return(asymmetricCipherKeyPair);
        }
Beispiel #14
0
        /// <summary>
        /// SM2解密
        /// </summary>
        /// <param name="privateKey">私钥</param>
        /// <param name="cipherData">密文</param>
        /// <returns></returns>
        public static string Decrypt(string privateKey, string cipherData)
        {
            byte[] cipherDataByte = Hex.Decode(cipherData);

            //获取一条SM2曲线参数
            X9ECParameters sm2EcParameters = GMNamedCurves.GetByName("sm2p256v1");
            //构造domain参数
            ECDomainParameters domainParameters = new ECDomainParameters(sm2EcParameters.Curve, sm2EcParameters.G, sm2EcParameters.N);

            BigInteger             privateKeyD          = new BigInteger(privateKey, 16);
            ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);

            SM2Engine sm2Engine = new SM2Engine();

            sm2Engine.Init(false, privateKeyParameters);

            byte[] arrayOfBytes = sm2Engine.ProcessBlock(cipherDataByte, 0, cipherDataByte.Length);
            return(Encoding.UTF8.GetString(arrayOfBytes));
        }
Beispiel #15
0
        /// <summary>
        /// SM2加密
        /// </summary>
        /// <param name="publicKey">公钥</param>
        /// <param name="data">明文</param>
        /// <returns>密文</returns>
        public static string Encrypt(string publicKey, string data)
        {
            // 获取一条SM2曲线参数
            X9ECParameters sm2EcParameters = GMNamedCurves.GetByName("sm2p256v1");
            // 构造domain参数
            ECDomainParameters domainParameters = new ECDomainParameters(sm2EcParameters.Curve, sm2EcParameters.G, sm2EcParameters.N);
            //提取公钥点
            ECPoint pukPoint = sm2EcParameters.Curve.DecodePoint(Hex.Decode(publicKey));
            // 公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥, 04的时候,可以去掉前面的04
            ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(pukPoint, domainParameters);

            SM2Engine sm2Engine = new SM2Engine();

            sm2Engine.Init(true, new ParametersWithRandom(publicKeyParameters, new SecureRandom()));

            byte[] input        = Encoding.UTF8.GetBytes(data);
            byte[] arrayOfBytes = sm2Engine.ProcessBlock(input, 0, input.Length);

            return(Hex.ToHexString(arrayOfBytes));
        }
Beispiel #16
0
        /**
         * sm2签名
         * @param userId ID值,若无约定,使用默认:1234567812345678
         * @param privateKey 私钥,二进制数据
         * @param sourceData 待签名数据
         * @return 返回der编码的签名值
         * @throws CryptoException
         */
        public static byte[] Sign(byte[] userId, byte[] privateKey, byte[] sourceData)
        {
            X9ECParameters         sm2p256v1        = GMNamedCurves.GetByName("sm2p256v1");
            ECDomainParameters     parameters       = new ECDomainParameters(sm2p256v1.Curve, sm2p256v1.G, sm2p256v1.N);
            ECPrivateKeyParameters priKeyParameters = new ECPrivateKeyParameters(new BigInteger(1, privateKey), parameters);
            SM2Signer            signer             = new SM2Signer();
            ICipherParameters    param = null;
            ParametersWithRandom pwr   = new ParametersWithRandom(priKeyParameters, new SecureRandom());

            if (userId != null)
            {
                param = new ParametersWithID(pwr, userId);
            }
            else
            {
                param = pwr;
            }
            signer.Init(true, param);
            signer.BlockUpdate(sourceData, 0, sourceData.Length);
            return(signer.GenerateSignature());
        }
Beispiel #17
0
        /**
         * 生成sm2公私钥对
         * @return
         */
        public static SM2KeyPair GenerateKeyPair()
        {
            X9ECParameters          sm2p256v1          = GMNamedCurves.GetByName("sm2p256v1");
            ECDomainParameters      parameters         = new ECDomainParameters(sm2p256v1.Curve, sm2p256v1.G, sm2p256v1.N);
            KeyGenerationParameters kgp                = new ECKeyGenerationParameters(parameters, new SecureRandom());
            ECKeyPairGenerator      ecKeyPairGenerator = new ECKeyPairGenerator();

            ecKeyPairGenerator.Init(kgp);
            ECPrivateKeyParameters ecpriv = null;
            ECPublicKeyParameters  ecpub  = null;

            //		int count = 0;
            do
            {
                AsymmetricCipherKeyPair keypair = ecKeyPairGenerator.GenerateKeyPair();
                ecpriv = (ECPrivateKeyParameters)keypair.Private;
                ecpub  = (ECPublicKeyParameters)keypair.Public;
            } while (ecpriv == null || ecpriv.D.Equals(BigInteger.Zero) ||
                     ecpriv.D.CompareTo(sm2p256v1.N) >= 0 || ecpriv.D.SignValue <= 0);
            byte[] privKey = FormartBigNum(ecpriv.D, 32);
            return(new SM2KeyPair(privKey, ecpub.Q.GetEncoded()));
        }
Beispiel #18
0
        ///**
        // * 私钥签名
        // * @param privateKey    私钥
        // * @param content       待签名内容
        // * @return
        // */
        //public static String sign(String privateKey, String content)
        //{
        //    //待签名内容转为字节数组
        //    byte[] message = Hex.Decode(content);

        //    //获取一条SM2曲线参数
        //    X9ECParameters sm2ECParameters = GMNamedCurves.GetByName("sm2p256v1");
        //    //构造domain参数
        //    ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.Curve,sm2ECParameters.G, sm2ECParameters.N);

        //    BigInteger privateKeyD = new BigInteger(privateKey, 16);
        //    ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);

        //    //创建签名实例
        //    SM2Signer sm2Signer = new SM2Signer();

        //    //初始化签名实例,带上ID,国密的要求,ID默认值:1234567812345678
        //    sm2Signer.Init(true, new ParametersWithID(new ParametersWithRandom(privateKeyParameters, SecureRandom.GetInstance("SHA1PRNG")), Strings.ToByteArray("1234567812345678")));

        //    //生成签名,签名分为两部分r和s,分别对应索引0和1的数组
        //    byte[] bigIntegers = sm2Signer.GenerateSignature();

        //    byte[] rBytes = modifyRSFixedBytes(bigIntegers[0].toByteArray());
        //    byte[] sBytes = modifyRSFixedBytes(bigIntegers[1].toByteArray());

        //    byte[] signBytes = ByteUtils.concatenate(rBytes, sBytes);
        //    String sign = Hex.toHexString(signBytes);

        //    return sign;
        //}

        ///**
        // * 将R或者S修正为固定字节数
        // * @param rs
        // * @return
        // */
        //private static byte[] modifyRSFixedBytes(byte[] rs)
        //{
        //    int length = rs.length;
        //    int fixedLength = 32;
        //    byte[] result = new byte[fixedLength];
        //    if (length < 32)
        //    {
        //        System.arraycopy(rs, 0, result, fixedLength - length, length);
        //    }
        //    else
        //    {
        //        System.arraycopy(rs, length - fixedLength, result, 0, fixedLength);
        //    }
        //    return result;
        //}

        /**
         * 验证签名
         * @param publicKey     公钥
         * @param content       待签名内容
         * @param sign          签名值
         * @return
         */
        public static bool verify(string publicKey, string content, string sign)
        {
            //待签名内容
            byte[] message  = Hex.Decode(content);
            byte[] signData = Hex.Decode(sign);

            // 获取一条SM2曲线参数
            X9ECParameters sm2EcParameters = GMNamedCurves.GetByName("sm2p256v1");
            // 构造domain参数
            ECDomainParameters domainParameters = new ECDomainParameters(sm2EcParameters.Curve, sm2EcParameters.G, sm2EcParameters.N);
            //提取公钥点
            ECPoint pukPoint = sm2EcParameters.Curve.DecodePoint(Hex.Decode(publicKey));
            // 公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥, 04的时候,可以去掉前面的04
            ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(pukPoint, domainParameters);

            //获取签名
            //BigInteger R = null;
            //BigInteger S = null;
            //byte[] rBy = new byte[33];
            //Array.Copy(signData, 0, rBy, 1, 32);
            //rBy[0] = 0x00;
            //byte[] sBy = new byte[33];
            //Array.Copy(signData, 32, sBy, 1, 32);
            //sBy[0] = 0x00;
            //R = new BigInteger(rBy);
            //S = new BigInteger(sBy);

            //创建签名实例
            SM2Signer        sm2Signer        = new SM2Signer();
            ParametersWithID parametersWithId = new ParametersWithID(publicKeyParameters, Strings.ToByteArray("1234567812345678"));

            sm2Signer.Init(false, parametersWithId);

            //验证签名结果
            bool verify = sm2Signer.VerifySignature(message);

            return(verify);
        }
Beispiel #19
0
        public override void Validate(SigType type, string signAlgName, byte[] tbsContent, byte[] signedValue)
        {
            if (type == SigType.Sign)
            {
                throw new ArgumentOutOfRangeException(nameof(type), "签名类型(type)必须是 Seal,不支持电子印章验证");
            }



            // 计算原文摘要
            GeneralDigest md = new SM3Digest();

            md.BlockUpdate(tbsContent, 0, tbsContent.Length);
            byte[] expect = new byte[32];
            md.DoFinal(expect, 0);

            SesSignature sesSignature = SesSignature.GetInstance(signedValue);
            TbsSign      toSign       = sesSignature.ToSign;

            byte[] expectDataHash = toSign.DataHash.GetOctets();


            // 比较原文摘要
            if (!Arrays.AreEqual(expect, expectDataHash))
            {
                //throw new InvalidSignedValueException("Signature.xml 文件被篡改,电子签章失效。("+ toSign.getPropertyInfo().getString() + ")");
            }

            //sg.initVerify(signCert);
            //sg.update(toSign.getEncoded("DER"));
            //if (!sg.verify(expSigVal))
            //{
            //    throw new InvalidSignedValueException("电子签章数据签名值不匹配,电子签章数据失效。");
            //}

            // 预期的电子签章数据,签章值
            byte[] expSigVal = sesSignature.Signature.GetOctets();

            //Signature sg = Signature(toSign.getSignatureAlgorithm().getId(),new BouncyCastleProvider());
            ISigner sg = SignerUtilities.GetSigner(GMObjectIdentifiers.sm2encrypt_with_sm3);

            byte[] certDER = toSign.Cert.GetOctets();

            //new  X509V1CertificateGenerator().Generate()

            // 构造证书对象
            //Certificate signCert = new CertificateFactory().engineGenerateCertificate(new ByteArrayInputStream(certDER));
            //X509Certificate x509Certificate = new X509Certificate(new X509CertificateStructure(TbsCertificateStructure.GetInstance(certDER), null, new DerBitString(certDER)));
            X509Certificate x509Certificate = new X509CertificateParser().ReadCertificate(certDER);
            //x509Certificate.Verify();
            AsymmetricKeyParameter p = x509Certificate.GetPublicKey();

            sg.Init(false, p);

            //System.Security.Cryptography.X509Certificates.X509Certificate x509 = new System.Security.Cryptography.X509Certificates.X509Certificate(certDER);
            //sg.Init(false,new ECPublicKeyParameters());


            // 获取一条SM2曲线参数
            X9ECParameters sm2EcParameters = GMNamedCurves.GetByName("sm2p256v1");
            // 构造domain参数
            ECDomainParameters domainParameters = new ECDomainParameters(sm2EcParameters.Curve, sm2EcParameters.G, sm2EcParameters.N);
            //提取公钥点
            ECPoint pukPoint = sm2EcParameters.Curve.DecodePoint(certDER);
            // 公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥, 04的时候,可以去掉前面的04
            ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(pukPoint, domainParameters);

            sg.Init(false, publicKeyParameters);


            byte[] input = toSign.GetDerEncoded();
            sg.BlockUpdate(input, 0, input.Length);

            bool pass = sg.VerifySignature(expSigVal);

            if (!pass)
            {
                throw new Exception();
            }
        }