public void VerifyMD5SignatureWithWrongHashLength()
        {
            RSAPKCS1SignatureDeformatter fmt = GetDefaultDeformatter("MD5");

            // wrong MD5 length
            byte[] hash = new byte [17];
            fmt.VerifySignature(hash, md5Signature);
        }
Beispiel #2
0
        public void VerifySHA1SignatureWithWrongHashLength()
        {
            RSAPKCS1SignatureDeformatter fmt = GetDefaultDeformatter("SHA1");

            // wrong SHA1 length
            byte[] hash = new byte [19];
            fmt.VerifySignature(hash, shaSignature);
        }
        public static void DigitalSignatureSample(string senderPrivatekey, string receirverspublickey, string texttoEncrypt)
        {
            UnicodeEncoding uc = new UnicodeEncoding();

            Console.WriteLine("Converting to bytes from text");

            //get bytearray from the message
            byte[] databytes = uc.GetBytes(texttoEncrypt);
            Console.WriteLine("Creating crypoclass instance");

            //Creating instance for RSACryptoservice provider as we are using for sender and receiver
            RSACryptoServiceProvider rsasender   = new RSACryptoServiceProvider();
            RSACryptoServiceProvider rsareceiver = new RSACryptoServiceProvider();

            //getting private and public key
            rsasender.FromXmlString(senderPrivatekey);
            rsareceiver.FromXmlString(receirverspublickey);
            Console.WriteLine("Creating signature formatter instance");

            //GEt signature from RSA
            RSAPKCS1SignatureFormatter signatureFormatter = new RSAPKCS1SignatureFormatter(rsasender);

            //set hashalgorithm
            signatureFormatter.SetHashAlgorithm("SHA1");

            //encrypt message
            Console.WriteLine("encrypting message");
            byte[] encryptedBytes = rsareceiver.Encrypt(databytes, false);
            //compute hash
            byte[] computedhash = new SHA1Managed().ComputeHash(encryptedBytes);
            Console.WriteLine("Creating signature");

            //create signature for the message
            byte[] signature = signatureFormatter.CreateSignature(computedhash);
            Console.WriteLine("Signature: " + Convert.ToBase64String(signature));
            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();

            //receive message then recompute hash
            Console.WriteLine("recomputing hash");
            byte[] recomputedHash = new SHA1Managed().ComputeHash(encryptedBytes);
            //signature deformatter
            Console.WriteLine("Creating signature dformatter instance");
            RSAPKCS1SignatureDeformatter signatureDFormatter = new RSAPKCS1SignatureDeformatter(rsareceiver);

            signatureDFormatter.SetHashAlgorithm("SHA1");

            //verify signature
            Console.WriteLine("verifying signature");
            if (!signatureDFormatter.VerifySignature(recomputedHash, signature))
            {
                Console.WriteLine("Signature did not match from sender");
            }
            Console.WriteLine("decrypting message");
            //decrypt message
            byte[] decryptedText = rsasender.Decrypt(encryptedBytes, false);
            Console.WriteLine(Encoding.UTF8.GetString(decryptedText));
        }
Beispiel #4
0
 /// <inheritdoc />
 protected internal override bool VerifySignature(byte[] data, byte[] signature)
 {
     using (var hash = CryptographicEngine.GetHashAlgorithm(this.Algorithm))
     {
         var deformatter = new RSAPKCS1SignatureDeformatter(this.Rsa);
         deformatter.SetHashAlgorithm(hash.ToString());
         return(deformatter.VerifySignature(hash.ComputeHash(data), signature));
     }
 }
Beispiel #5
0
        /// <summary>
        /// 公钥验签
        /// </summary>
        /// <param name="xmlPublicKey">公钥</param>
        /// <param name="rgbHash">待签名数据的hash值</param>
        /// <param name="signData">签名的值</param>
        /// <param name="hashType">指定hash的类型(MD5|SHA1)</param>
        /// <returns>签名是否符合</returns>
        public static bool SignatureDeformatter(string xmlPublicKey, byte[] rgbHash, byte[] signData, string hashType)
        {
            System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();
            RSA.FromXmlString(xmlPublicKey);
            RSAPKCS1SignatureDeformatter RSADeformatter = new RSAPKCS1SignatureDeformatter(RSA);

            RSADeformatter.SetHashAlgorithm(hashType);
            return(RSADeformatter.VerifySignature(rgbHash, signData));
        }
        public void VerifySignatureNullSignature()
        {
            RSAPKCS1SignatureDeformatter fmt = new RSAPKCS1SignatureDeformatter();

            fmt.SetHashAlgorithm("SHA1");
            fmt.SetKey(rsa);
            byte[] hash = new byte [20];
            fmt.VerifySignature(hash, null);
        }
 public static bool SignatureValidate(byte[] inputData, byte[] signatureData, byte[] publicKey)
 {
     using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) {
         rsa.ImportCspBlob(publicKey);
         RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(rsa);
         deformatter.SetHashAlgorithm("MD5");
         return(deformatter.VerifySignature(inputData, signatureData));
     }
 }
        public void VerifySHA1SignatureWithWrongSignatureLength()
        {
            RSAPKCS1SignatureDeformatter fmt = GetDefaultDeformatter("SHA1");

            // wrong signature length
            byte[] hash         = new byte [20];
            byte[] badSignature = new byte [shaSignature.Length - 1];
            Assert.IsFalse(fmt.VerifySignature(hash, badSignature), "VerifySignature(SHA1, badSign)");
        }
 public bool VerifySignature(byte[] hasOfDataToSign, byte[] signature)
 {
     using (var rsa = new RSACryptoServiceProvider(2048)){
         rsa.ImportParameters(this._publicKey);
         var rsaDeformater = new RSAPKCS1SignatureDeformatter(rsa);
         rsaDeformater.SetHashAlgorithm("SHA256");
         return(rsaDeformater.VerifySignature(hasOfDataToSign, signature));
     }
 }
        public void VerifyMD5SignatureWithWrongSignatureLength()
        {
            RSAPKCS1SignatureDeformatter fmt = GetDefaultDeformatter("MD5");

            // wrong signature length
            byte[] hash         = new byte [16];
            byte[] badSignature = new byte [md5Signature.Length - 1];
            Assert.IsFalse(fmt.VerifySignature(hash, badSignature), "VerifySignature(MD5, badSign)");
        }
        /// <summary>
        ///     Verify a digital signature from file.
        /// </summary>
        /// <param name="sigFileName">Name of the sig file.</param>
        /// <param name="fileName">Name of the file.</param>
        /// <param name="publicKey">The public key.</param>
        /// <returns>
        ///     <c>true</c> on verified signature; otherwise, <c>false</c>.
        /// </returns>
        /// <externalUnit/>
        /// <revision revisor="dev03" date="02/19/09" version="1.0.8.6">
        ///     Method created.
        /// </revision>
        public bool VerifySignature(
            string sigFileName,
            string fileName,
            string publicKey)
        {
            // local variable declarations
            bool verified;

            byte[] fileHash;
            byte[] signature;

            this.AsymmetricCrypto.FromXmlString(publicKey);

            // validate signature and file
            if (File.Exists(sigFileName) == false ||
                File.Exists(fileName) == false)
            {
                return(false);
            }

            // create file hash
            using (FileStream file = new FileStream(
                       fileName,
                       FileMode.Open,
                       FileAccess.Read))
            {
                SHA1 sha1 = new SHA1CryptoServiceProvider();
                fileHash = sha1.ComputeHash(file);
            }

            // read in digital signature
            using (FileStream file = new FileStream(
                       sigFileName,
                       FileMode.Open,
                       FileAccess.Read))
            {
                using (BinaryReader reader = new BinaryReader(file))
                {
                    FileInfo f = new FileInfo(sigFileName);
                    signature = reader.ReadBytes((int)f.Length);
                }
            }

            // verify digital signature
            var rsaDeformatter =
                new RSAPKCS1SignatureDeformatter(this.AsymmetricCrypto);

            rsaDeformatter.SetHashAlgorithm("SHA1");
            verified = false;
            if (rsaDeformatter.VerifySignature(fileHash, signature))
            {
                verified = true;
            }

            return(verified);
        }
Beispiel #12
0
        private void CheckSingleSignOnHandler(object sender, EventArgs e)
        {
            var app = sender as HttpApplication;
            NameValueCollection form = null;
            var authHeader           = app.Request.Headers["SSOAuth"];

            if (!string.IsNullOrEmpty(authHeader))
            {
                form = FormDecode(authHeader);
            }
            else if (app.Request.Cookies.Keys.OfType <string>().Contains("SSOAuth"))
            {
                var ssoAuthCookie = app.Request.Cookies["SSOAuth"];
                form = HttpUtility.ParseQueryString(Encoding.UTF8.GetString(Convert.FromBase64String(ssoAuthCookie.Value)));
            }
            else
            {
                switch (app.Request.RequestType)
                {
                case "GET":
                {
                    var content = app.Request.Url.Query;
                    form = HttpUtility.ParseQueryString(content);
                }
                break;

                case "PUT":
                case "POST":
                    form = app.Request.Form;
                    break;
                }
            }

            if (form != null && form.Keys.OfType <string>().Contains("Token"))
            {
                var signature   = Convert.FromBase64String(form["Token"]);
                var noTokenForm = new NameValueCollection(form);
                noTokenForm.Remove("Token");
                var contentString = FormEncode(noTokenForm);
                var hash          = SHA1Managed.Create().ComputeHash(Encoding.Unicode.GetBytes(contentString));

                var key = GetPublicKey();

                var deformatter = new RSAPKCS1SignatureDeformatter(key);
                deformatter.SetHashAlgorithm("SHA1");
                var verify = deformatter.VerifySignature(hash, signature);
                if (verify)
                {
                    CreatePrinciple(form);
                    return;
                }
            }

            app.Response.StatusCode = 404;
            app.CompleteRequest();
        }
Beispiel #13
0
        /// <summary>
        /// Validates the signature.
        /// </summary>
        /// <param name="hashValue">The hash value.</param>
        /// <param name="signedHashValue">The signed hash value.</param>
        /// <param name="cspKeyBlob">The CSP key Blob of the asserted signer.</param>
        /// <returns></returns>
        public static bool ValidateSignature(byte[] hashValue, byte[] signedHashValue, byte[] cspKeyBlob)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

            rsa.ImportCspBlob(cspKeyBlob);
            RSAPKCS1SignatureDeformatter rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa);

            rsaDeformatter.SetHashAlgorithm("SHA1");
            return(rsaDeformatter.VerifySignature(hashValue, signedHashValue));
        }
            public static bool VerifySignature(string publicKeyString, byte[] hashOfDataToSign, byte[] signature)
            {
                using (var rsa = RSAPEMHelper.PublicKeyFromPem(publicKeyString))
                {
                    var rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa);
                    rsaDeformatter.SetHashAlgorithm("SHA256");

                    return(rsaDeformatter.VerifySignature(hashOfDataToSign, signature));
                }
            }
 private static bool VerifySignedMessage(string message, byte[] signature)
 {
     using (SHA256 sha = SHA256Managed.Create())
     {
         var hashValue   = sha.ComputeHash(Encoding.UTF8.GetBytes(message));
         var deformatter = new RSAPKCS1SignatureDeformatter(rsa);
         deformatter.SetHashAlgorithm("SHA256");
         return(deformatter.VerifySignature(hashValue, signature));
     }
 }
 public bool VerifySignature(string text, byte[] signature)
 {
     using (var rsa = new RSACryptoServiceProvider(2048))
     {
         rsa.ImportParameters(_publicKey);
         var rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa);
         rsaDeformatter.SetHashAlgorithm("SHA256");
         return(rsaDeformatter.VerifySignature(HashText(text), signature));
     }
 }
 /// <summary>
 /// Verify digital signature
 /// </summary>
 /// <param name="hashSumOfMessage">Hash sum of checking message</param>
 /// <param name="digitalSignature">Digital signature</param>
 /// <param name="publicKey">Public key from other side</param>
 /// <returns>Is valid</returns>
 public bool IsValidDigitalSignature(byte[] hashSumOfMessage, byte[] digitalSignature, string publicKey)
 {
     using (RSACryptoServiceProvider provider = new RSACryptoServiceProvider())
     {
         provider.FromXmlString(publicKey);
         RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(provider);
         deformatter.SetHashAlgorithm("SHA1");
         return(deformatter.VerifySignature(hashSumOfMessage, digitalSignature));
     }
 }
        public void VerifySignatureWithBadHash()
        {
            RSAPKCS1SignatureDeformatter fmt = new RSAPKCS1SignatureDeformatter();

            fmt.SetKey(rsa);
            // no hash algorithm
            byte[] hash      = new byte [1];
            byte[] signature = new byte [1];
            fmt.VerifySignature(hash, signature);
        }
        private bool VerifySign(byte[] hashBytes, byte[] signBytes)
        {
            using (RSACryptoServiceProvider rsaAlg = GetProviderFromKey(_keyPairOrPublicKey))
            {
                var deformatter = new RSAPKCS1SignatureDeformatter(rsaAlg);
                deformatter.SetHashAlgorithm(HashAlgName);

                return(deformatter.VerifySignature(hashBytes, signBytes));
            }
        }
        public void VerifySignatureNullHash()
        {
            RSAPKCS1SignatureDeformatter fmt = new RSAPKCS1SignatureDeformatter();

            fmt.SetHashAlgorithm("SHA1");
            fmt.SetKey(rsa);
            byte[] hash      = null;
            byte[] signature = new byte [128];
            fmt.VerifySignature(hash, signature);
        }
Beispiel #21
0
 public bool Verify(Hash hash, Signature signature)
 {
     using (var rsa = new RSACryptoServiceProvider())
     {
         rsa.ImportParameters(_publicKey);
         var deformatter = new RSAPKCS1SignatureDeformatter(rsa);
         deformatter.SetHashAlgorithm("SHA256");
         return(deformatter.VerifySignature(hash, signature));
     }
 }
Beispiel #22
0
            public static bool VerifySignature(string publicKeyPath, byte[] hashOfDataToSign, byte[] signature)
            {
                using (var rsa = Crypto.DecodeX509PublicKey(File.ReadAllText(publicKeyPath)))
                {
                    var rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa);
                    rsaDeformatter.SetHashAlgorithm("SHA256");

                    return(rsaDeformatter.VerifySignature(hashOfDataToSign, signature));
                }
            }
        public bool VerifySignature(byte[] hashOfDataToSign, byte[] signature)
        {
            using (var rsa = Crypto.DecodeX509PublicKey(_publicKey))
            {
                var rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa);
                rsaDeformatter.SetHashAlgorithm("SHA256");

                return(rsaDeformatter.VerifySignature(hashOfDataToSign, signature));
            }
        }
Beispiel #24
0
        // TODO: This doesn't work on mono for some reason. Investigate.
        public static bool IsSignedBy(TmodFile mod, string xmlPublicKey)
        {
            var f = new RSAPKCS1SignatureDeformatter();
            var v = AsymmetricAlgorithm.Create("RSA");

            f.SetHashAlgorithm("SHA1");
            v.FromXmlString(xmlPublicKey);
            f.SetKey(v);
            return(f.VerifySignature(mod.hash, mod.signature));
        }
Beispiel #25
0
        public bool SignatureDeformatter(string p_strKeyPublic, byte[] HashbyteDeformatter, byte[] DeformatterData)
        {
            RSACryptoServiceProvider key = new RSACryptoServiceProvider();

            key.FromXmlString(p_strKeyPublic);
            RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key);

            deformatter.SetHashAlgorithm("MD5");
            return(deformatter.VerifySignature(HashbyteDeformatter, DeformatterData));
        }
Beispiel #26
0
 public static bool RSAVerifySignature(string xmlPublicKey, byte[] hashbytes, byte[] signatureBytes)
 {
     using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
     {
         rsa.FromXmlString(xmlPublicKey);
         RSAPKCS1SignatureDeformatter rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa);
         rsaDeformatter.SetHashAlgorithm("MD5");
         return(rsaDeformatter.VerifySignature(hashbytes, signatureBytes));
     }
 }
        public void VerifySignatureNullHashAlgorithm()
        {
            RSAPKCS1SignatureDeformatter fmt = new RSAPKCS1SignatureDeformatter();
            HashAlgorithm hash = null;

            byte[] data = new byte [20];
            // no hash algorithm
            byte[] signature = new byte [1];
            fmt.VerifySignature(hash, signature);
        }
Beispiel #28
0
        public bool VerifySignature(byte[] hashToSign, byte[] signature, KeyStorageOption keyStorageOption,
                                    string publicKeyFilePath = "")
        {
            bool isValid = default;

            switch (keyStorageOption)
            {
            case KeyStorageOption.InMemory:
            {
                using var rsaProvider = new RSACryptoServiceProvider
                      {
                          PersistKeyInCsp = false,
                      };

                rsaProvider.ImportParameters(_publicKey);
                var rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsaProvider);
                rsaDeformatter.SetHashAlgorithm("SHA512");
                isValid = rsaDeformatter.VerifySignature(hashToSign, signature);
                break;
            }

            case KeyStorageOption.Xml:
            {
                using var rsaProvider = new RSACryptoServiceProvider
                      {
                          PersistKeyInCsp = false,
                      };

                rsaProvider.FromXmlString(File.ReadAllText(publicKeyFilePath));
                var rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsaProvider);
                rsaDeformatter.SetHashAlgorithm("SHA512");
                isValid = rsaDeformatter.VerifySignature(hashToSign, signature);
                break;
            }

            case KeyStorageOption.Csp:
            {
                var cspParameters = new CspParameters
                {
                    KeyContainerName = containerName,
                };

                using var rsaProvider = new RSACryptoServiceProvider(4096, cspParameters)
                      {
                          PersistKeyInCsp = true,
                      };
                var rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsaProvider);
                rsaDeformatter.SetHashAlgorithm("SHA512");
                isValid = rsaDeformatter.VerifySignature(hashToSign, signature);
                break;
            }
            }

            return(isValid);
        }
        public bool IsJwtValid(String jwt)
        {
            string[] jwtParts = jwt.Split('.');

            String decodedHeader  = SafeDecodeBase64(jwtParts[0]);
            String decodedPayload = SafeDecodeBase64(jwtParts[1]);

            id_token_obj = new JObject
            {
                { "decoded_header", decodedHeader },
                { "decoded_payload", decodedPayload }
            };

            String keyId    = JObject.Parse(decodedHeader).GetValue("kid").ToString();
            JToken keyFound = (JToken)System.Web.HttpContext.Current.Application[keyId];

            if (keyFound == null)
            {
                keyFound = FetchKeys(keyId);
                if (keyFound == null)
                {
                    throw new JwtValidationException("Key not found in JWKS endpoint or Application State");
                }
            }

            if (!JObject.Parse(decodedPayload).GetValue("iss").ToString().Equals(issuer))
            {
                throw new JwtValidationException("Issuer not validated");
            }

            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

            rsa.ImportParameters(
                new RSAParameters()
            {
                Modulus  = getPaddedBase64String(keyFound["n"].ToString()),
                Exponent = getPaddedBase64String(keyFound["e"].ToString())
            });

            SHA256 sha256 = SHA256.Create();

            byte[] hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(jwtParts[0] + '.' + jwtParts[1]));

            RSAPKCS1SignatureDeformatter rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa);

            rsaDeformatter.SetHashAlgorithm("SHA256");
            if (rsaDeformatter.VerifySignature(hash, getPaddedBase64String(jwtParts[2])))
            {
                return(true); //Jwt Validated
            }
            else
            {
                throw new JwtValidationException("Could not validate signature of JWT");
            }
        }
        internal bool VerifySignature(RSA rsa)
        {
            RSAPKCS1SignatureDeformatter v = new RSAPKCS1SignatureDeformatter(rsa);

            switch (m_signaturealgo)
            {
            // MD2 with RSA encryption
            case "1.2.840.113549.1.1.2":
                // maybe someone installed MD2 ?
                v.SetHashAlgorithm("MD2");
                break;

            // MD4 with RSA encryption
            case "1.2.840.113549.1.1.3":
                // maybe someone installed MD4 ?
                v.SetHashAlgorithm("MD4");
                break;

            // MD5 with RSA encryption
            case "1.2.840.113549.1.1.4":
                v.SetHashAlgorithm("MD5");
                break;

            // SHA-1 with RSA Encryption
            case "1.2.840.113549.1.1.5":
            case "1.3.14.3.2.29":
                v.SetHashAlgorithm("SHA1");
                break;

            // SHA-256 with RSA Encryption
            case "1.2.840.113549.1.1.11":
                v.SetHashAlgorithm("SHA256");
                break;

            // SHA-384 with RSA Encryption
            case "1.2.840.113549.1.1.12":
                v.SetHashAlgorithm("SHA384");
                break;

            // SHA-512 with RSA Encryption
            case "1.2.840.113549.1.1.13":
                v.SetHashAlgorithm("SHA512");
                break;

            // SHA1-1 with DSA
            case "1.2.840.10040.4.3":
                // invalid but this can occurs when building a bad chain - e.g. missing certificate(s)
                // we return false so we can report the "chain" error to the user (not an exception)
                return(false);

            default:
                throw new CryptographicException("Unsupported hash algorithm: " + m_signaturealgo);
            }
            return(v.VerifySignature(this.Hash, this.Signature));
        }
Beispiel #31
0
 /// <summary>
 /// Verifies a PKS1 signature of SHA1 digest
 /// </summary>
 /// <param name="xParam">Keys</param>
 /// <param name="xHash">Hash to sign</param>
 /// <param name="xSignature">Outputs the signature</param>
 /// <returns></returns>
 public static bool SignatureVerify(RSAParameters xParam, byte[] xHash, byte[] xSignature)
 {
     RSACryptoServiceProvider xRSACrypto = new RSACryptoServiceProvider();
     RSAPKCS1SignatureDeformatter xRSASigDeformat = new RSAPKCS1SignatureDeformatter();
     try { xRSACrypto.ImportParameters(xParam); }
     catch (Exception xerror) { throw xerror; }
     xRSASigDeformat.SetHashAlgorithm("SHA1");
     xRSASigDeformat.SetKey(xRSACrypto);
     try { return xRSASigDeformat.VerifySignature(xHash, xSignature); }
     catch { throw CryptoExcepts.CryptoVeri; }
 }
        public static void VerifyKnownSignature()
        {
            byte[] hash = "012d161304fa0c6321221516415813022320620c".HexToByteArray();
            byte[] sig;

            using (RSA key = RSAFactory.Create())
            {
                key.ImportParameters(TestData.RSA1024Params);
                RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);
                formatter.SetHashAlgorithm("SHA1");
                sig = formatter.CreateSignature(hash);

                byte[] expectedSig =
                    ("566390012605b1c4c01c3c2f91ce27d19476ab7131d9ee9cd1b811afb2be02ab6b498b862f0b2368ed6b09ccc9e0ec0d4f97a4f318f4f11" +
                     "ae882a1131012dc35d2e0b810a38e05da71d291e88b306605c9d34815091641370bd7db7a87b115bd427fcb9993bc5ba2bd518745aef80c" +
                     "a4557cfa1d827ff1610595d8eeb4c15073").HexToByteArray();
                Assert.Equal(expectedSig, sig);
            }

            using (RSA key = RSAFactory.Create()) // Test against a different instance
            {
                key.ImportParameters(TestData.RSA1024Params);
                RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key);
                deformatter.SetHashAlgorithm("SHA1");
                bool verified = deformatter.VerifySignature(hash, sig);
                Assert.True(verified);

                sig[3] ^= 0xff;
                verified = deformatter.VerifySignature(hash, sig);
                Assert.False(verified);
            }
        }