Exemplo n.º 1
0
        public bool verify(byte[] msg, byte[] signature)
        {
            var verifier = new Ed25519Signer();

            verifier.Init(false, publicKey);
            verifier.BlockUpdate(msg, 0, msg.Length);
            return(verifier.VerifySignature(signature));
        }
Exemplo n.º 2
0
        bool ICryptoLibrary.VerifyEd25519(byte[] plainText, byte[] signature, byte[] publicKey)
        {
            var signer = new Ed25519Signer();

            signer.Init(false, new Ed25519PublicKeyParameters(publicKey, 0));
            signer.BlockUpdate(plainText, 0, plainText.Length);
            return(signer.VerifySignature(signature));
        }
Exemplo n.º 3
0
        public static bool Verify(byte[] data, byte[] signature, string publicKey)
        {
            Ed25519Signer verifier = new Ed25519Signer();

            verifier.Init(false, publicKey.ToPublicKeyCipherParamsFromHex());
            verifier.BlockUpdate(data, 0, data.Length);
            return(verifier.VerifySignature(signature));
        }
Exemplo n.º 4
0
        // Verifies signature with signer’s public key using Bouncy Castle
        public static bool Verify(string data, string signature, string publicKey)
        {
            var verifier = new Ed25519Signer();

            verifier.Init(false, new Ed25519PublicKeyParameters(Hex.Decode(publicKey), 0));
            verifier.BlockUpdate(Encoding.UTF8.GetBytes(data), 0, Encoding.UTF8.GetBytes(data).Length);

            return(verifier.VerifySignature(Hex.Decode(signature)));
        }
        public override bool Verify(byte[] input, byte[] signature)
        {
            var validator = new Ed25519Signer();

            validator.Init(false, edDsaKey.KeyParameters);
            validator.BlockUpdate(input, 0, input.Length);

            return(validator.VerifySignature(signature));
        }
Exemplo n.º 6
0
        /// <summary>
        /// Perform signature verification against the sender address
        /// </summary>
        /// <param name="address">Address to verify</param>
        /// <returns>bool</returns>
        public bool Verify(Address address)
        {
            if (this.logic == null)
            {
                return(false);
            }
            else if (this.sig != null && this.msig != null)
            {
                return(false);
            }
            else
            {
                try
                {
                    Logic.CheckProgram(this.logic, this.args);
                }
                catch (Exception)
                {
                    return(false);
                }

                if (this.sig == null && this.msig == null)
                {
                    try
                    {
                        return(address.Equals(this.ToAddress()));
                    }
                    catch (Exception)
                    {
                        return(false);
                    }
                }

                if (this.sig != null)
                {
                    try
                    {
                        var pk     = new Ed25519PublicKeyParameters(address.Bytes, 0);
                        var signer = new Ed25519Signer();
                        signer.Init(false, pk); //false代表用于VerifySignature
                        signer.BlockUpdate(this.BytesToSign(), 0, this.BytesToSign().Length);
                        return(signer.VerifySignature(this.sig.Bytes));
                    }
                    catch (Exception err)
                    {
                        Console.WriteLine("Message = " + err.Message);
                        return(false);
                    }
                }
                else
                {
                    return(this.msig.Verify(this.BytesToSign()));
                }
            }
        }
Exemplo n.º 7
0
        public bool Verify(byte[] msg, byte[] sig, byte[] pubKey)
        {
            var keyedHash = Blake2b.GetDigest(msg);
            var publicKey = new Ed25519PublicKeyParameters(pubKey, 0);
            var verifier  = new Ed25519Signer();

            verifier.Init(false, publicKey);
            verifier.BlockUpdate(keyedHash, 0, keyedHash.Length);

            return(verifier.VerifySignature(sig));
        }
Exemplo n.º 8
0
        public bool VerifyStamp(TimestampDao timestamp)
        {
            var fileHash  = timestamp.FileHash.ToUpper().FromBase32();
            var signature = timestamp.Signature.ToUpper().FromBase32();
            var publicKey = new Ed25519PublicKeyParameters(timestamp.PublicKey.ToUpper().FromBase32(), 0);

            var verifier = new Ed25519Signer();

            verifier.Init(false, publicKey);
            verifier.BlockUpdate(fileHash, 0, fileHash.Length);
            return(verifier.VerifySignature(signature));
        }
Exemplo n.º 9
0
        /// <summary>
        /// Performs signature verification
        /// </summary>
        /// <param name="message">raw message to verify</param>
        /// <returns>bool</returns>
        public bool Verify(byte[] message)
        {
            if (this.version == 1 && this.threshold > 0 && this.subsigs.Count != 0)
            {
                if (this.threshold > this.subsigs.Count)
                {
                    return(false);
                }
                else
                {
                    int       verifiedCount = 0;
                    Signature emptySig      = new Signature();

                    for (int i = 0; i < this.subsigs.Count; ++i)
                    {
                        MultisigSubsig subsig = subsigs[i];
                        if (!subsig.sig.Equals(emptySig))
                        {
                            try
                            {
                                var pk     = subsig.key;
                                var signer = new Ed25519Signer();
                                signer.Init(false, pk); //for verify
                                signer.BlockUpdate(message, 0, message.Length);
                                bool verified = signer.VerifySignature(subsig.sig.Bytes);
                                if (verified)
                                {
                                    ++verifiedCount;
                                }
                            }
                            catch (Exception var9)
                            {
                                throw new ArgumentException("verification of subsig " + i + "failed", var9);
                            }
                        }
                    }

                    if (verifiedCount < this.threshold)
                    {
                        return(false);
                    }
                    else
                    {
                        return(true);
                    }
                }
            }
            else
            {
                return(false);
            }
        }
Exemplo n.º 10
0
        /// <inheritdoc/>
        public ValidationResult VerifySignature(string signature, byte[] dataToVerify)
        {
            ValidationResult res = ValidationResult.Invalid;

            if (!CheckSecurityMode(signature, ref res))
            {
                return(res);
            }

            // convert signature
            byte[] bHash = Convert.FromBase64String(signature);
            _signer.BlockUpdate(dataToVerify, 0, dataToVerify.Length);
            // verify
            return(_signer.VerifySignature(bHash) ? ValidationResult.Valid : ValidationResult.Invalid);
        }
Exemplo n.º 11
0
        /// <summary>
        /// verifyBytes verifies that the signature for the message is valid for the public key.
        /// The message should have been prepended with "MX" when signing.
        /// </summary>
        /// <param name="message">the message that was signed</param>
        /// <param name="signature">signature</param>
        /// <returns>true if the signature is valid</returns>
        public bool VerifyBytes(byte[] message, Signature signature)
        {
            var pk = new Ed25519PublicKeyParameters(this.Bytes, 0);
            // prepend the message prefix
            List <byte> prefixBytes = new List <byte>(BYTES_SIGN_PREFIX);

            prefixBytes.AddRange(message);

            // verify signature
            // Generate new signature
            var signer = new Ed25519Signer();

            signer.Init(false, pk);
            signer.BlockUpdate(prefixBytes.ToArray(), 0, prefixBytes.ToArray().Length);
            return(signer.VerifySignature(signature.Bytes));
        }
Exemplo n.º 12
0
        private void BasicSigTest()
        {
            Ed25519PrivateKeyParameters privateKey = new Ed25519PrivateKeyParameters(
                Hex.DecodeStrict("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"), 0);
            Ed25519PublicKeyParameters publicKey = new Ed25519PublicKeyParameters(
                Hex.DecodeStrict("d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"), 0);

            byte[] sig = Hex.Decode("e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b");

            ISigner signer = new Ed25519Signer();

            signer.Init(true, privateKey);

            IsTrue(AreEqual(sig, signer.GenerateSignature()));

            signer.Init(false, publicKey);

            IsTrue(signer.VerifySignature(sig));
        }
Exemplo n.º 13
0
        private static void EdDsaWithBouncyCastle()
        {
            // message to sign & verify
            var message = Encoding.UTF8.GetBytes("Bob Loblaw");

            // private/public key generation
            var keyPairGenerator = new Ed25519KeyPairGenerator();

            keyPairGenerator.Init(new Ed25519KeyGenerationParameters(new SecureRandom()));
            var keyPair = keyPairGenerator.GenerateKeyPair();

            var privateKey = (Ed25519PrivateKeyParameters)keyPair.Private;
            var publicKey  = (Ed25519PublicKeyParameters)keyPair.Public;

            // keys are 32-bytes each
            var privateKeyBytes = privateKey.GetEncoded();
            var publicKeyBytes  = publicKey.GetEncoded();

            Console.WriteLine("Private key = " + Convert.ToBase64String(privateKeyBytes));
            Console.WriteLine("Public key = " + Convert.ToBase64String(publicKeyBytes));

            // signature generation
            var signer = new Ed25519Signer();

            signer.Init(true, privateKey);
            signer.BlockUpdate(message, 0, message.Length);

            byte[] signature = signer.GenerateSignature();
            Console.WriteLine("Signature = " + Convert.ToBase64String(signature));

            // signature validation
            var validator = new Ed25519Signer();

            validator.Init(false, publicKey);
            validator.BlockUpdate(message, 0, message.Length);

            bool isValidSignature = validator.VerifySignature(signature);

            Console.WriteLine("Signature is valid: " + isValidSignature);
        }
Exemplo n.º 14
0
        /// <summary>
        /// Verifies the signature.
        /// </summary>
        /// <param name="file">The file.</param>
        /// <param name="signature">The signature.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public bool VerifySignature(FileInfo file, string signature)
        {
            if (!KeysExist())
            {
                Console.WriteLine("Keys do not exist");
                return(false);
            }
            if (signature == null)
            {
                Console.WriteLine("Signature at path {0} is null", file.FullName);
                return(false);
            }

            var data = File.ReadAllBytes(file.FullName);

            var validator = new Ed25519Signer();

            validator.Init(false, new Ed25519PublicKeyParameters(GetPublicKey(), 0));
            validator.BlockUpdate(data, 0, data.Length);

            return(validator.VerifySignature(Convert.FromBase64String(signature)));
        }
Exemplo n.º 15
0
        /// <summary>
        /// Verifies a signature to be authentic
        /// </summary>
        /// <param name="originalSignature">The signature which is be verified</param>
        /// <param name="publicKey">the public key used for the verification</param>
        /// <param name="data">the data which is signed</param>
        /// <returns>true if signature is authentic, false if not</returns>
        public bool Verify(byte[] originalSignature, byte[] publicKey, byte[] data)
        {
            Ed25519PublicKeyParameters pubKey = null;

            try
            {
                pubKey = (Ed25519PublicKeyParameters)CreateAsymmetricKeyParameterFromPublicKeyInfo(publicKey);
            }
            catch (InvalidCastException exception)
            {
                string message = "Public Key Import Failed!\n" +
                                 $"{exception.Message}.\n" +
                                 "The contents of the source do not represent a valid Ed25519 key parameter\n" +
                                 "Verify that the key is not corrupted.\n" +
                                 "- or - Verify that the correct key is selected.";
                throw new CryptoException(message, exception);
            }
            var signer = new Ed25519Signer();

            signer.Init(false, pubKey);
            signer.BlockUpdate(data, 0, data.Length);
            return(signer.VerifySignature(originalSignature));
        }
Exemplo n.º 16
0
        /// <inheritdoc/>
        public override bool Verify(byte[] input, byte[] signature)
        {
            if (input == null || input.Length == 0)
            {
                throw new ArgumentNullException(nameof(input));
            }

            if (signature == null || signature.Length == 0)
            {
                throw new ArgumentNullException(nameof(signature));
            }

            if (EdDsaKey.Curve.Equals("Ed25519"))
            {
                var publicKey = (Ed25519PublicKeyParameters)EdDsaKey.KeyParameter;
                var validator = new Ed25519Signer();
                validator.Init(forSigning: false, publicKey);
                validator.BlockUpdate(input, off: 0, len: input.Length);

                return(validator.VerifySignature(signature));
            }

            throw new ArgumentException($"Unsupported EdDSA curve: \"{EdDsaKey.Curve}\".");
        }
Exemplo n.º 17
0
        public override PasetoSecurityToken Verify(PasetoToken token, IEnumerable <SecurityKey> signingKeys)
        {
            if (token == null)
            {
                throw new ArgumentNullException(nameof(token));
            }
            if (signingKeys == null || !signingKeys.Any())
            {
                throw new ArgumentNullException(nameof(signingKeys));
            }

            var keys = signingKeys.OfType <EdDsaSecurityKey>().ToList();

            if (!keys.Any())
            {
                throw new SecurityTokenInvalidSigningKeyException($"PASETO v2 requires key of type {typeof(EdDsaSecurityKey)}");
            }

            if (token.Version != PasetoConstants.Versions.V2)
            {
                throw new ArgumentException("Invalid PASETO version");
            }
            if (token.Purpose != PasetoConstants.Purposes.Public)
            {
                throw new ArgumentException("Invalid PASETO purpose");
            }

            // decode payload
            var payload = Base64UrlEncoder.DecodeBytes(token.EncodedPayload);

            if (payload.Length < 64)
            {
                throw new SecurityTokenInvalidSignatureException("Payload does not contain signature");
            }

            // extract signature from payload (rightmost 64 bytes)
            var signature = new byte[64];

            Buffer.BlockCopy(payload, payload.Length - 64, signature, 0, 64);

            // decode payload JSON
            var message = new byte[payload.Length - 64];

            Buffer.BlockCopy(payload, 0, message, 0, payload.Length - 64);
            token.SetPayload(Encoding.UTF8.GetString(message));

            // pack
            var signedMessage = PreAuthEncode(new[]
            {
                Encoding.UTF8.GetBytes(PublicHeader),
                message,
                Base64UrlEncoder.DecodeBytes(token.EncodedFooter ?? string.Empty)
            });

            // verify signature using valid keys
            foreach (var publicKey in keys)
            {
                var signer = new Ed25519Signer();
                signer.Init(false, publicKey.KeyParameters);
                signer.BlockUpdate(signedMessage, 0, signedMessage.Length);

                var isValidSignature = signer.VerifySignature(signature);
                if (isValidSignature)
                {
                    return(new PasetoSecurityToken(token));
                }
            }

            throw new SecurityTokenInvalidSignatureException("Invalid PASETO signature");
        }
Exemplo n.º 18
0
        public void Verify(Key key, SignMessage msg)
        {
            string alg = FindAttr("alg", msg).AsString();

            IDigest digest;
            IDigest digest2;

            switch (alg)
            {
            case "RS256":
            case "ES256":
            case "PS256":
            case "HS256":
                digest  = new Sha256Digest();
                digest2 = new Sha256Digest();
                break;

            case "RS384":
            case "ES384":
            case "PS384":
            case "HS384":
                digest  = new Sha384Digest();
                digest2 = new Sha384Digest();
                break;

            case "RS512":
            case "ES512":
            case "PS512":
            case "HS512":
                digest  = new Sha512Digest();
                digest2 = new Sha512Digest();
                break;

            case "EdDSA":
                digest  = null;
                digest2 = null;
                break;

            default:
                throw new JOSE_Exception("Unknown signature algorithm");
            }



            switch (alg)
            {
            case "RS256":
            case "RS384":
            case "RS512": {
                if (key.AsString("kty") != "RSA")
                {
                    throw new JOSE_Exception("Wrong Key");
                }
                RsaDigestSigner  signer = new RsaDigestSigner(digest);
                RsaKeyParameters pub    = new RsaKeyParameters(false, key.AsBigInteger("n"), key.AsBigInteger("e"));

                signer.Init(false, pub);
                signer.BlockUpdate(protectedB64, 0, protectedB64.Length);
                signer.BlockUpdate(rgbDot, 0, 1);
                signer.BlockUpdate(msg.payloadB64, 0, msg.payloadB64.Length);
                if (!signer.VerifySignature(signature))
                {
                    throw new JOSE_Exception("Message failed to verify");
                }
            }
            break;

            case "PS256":
            case "PS384":
            case "PS512": {
                PssSigner        signer = new PssSigner(new RsaEngine(), digest, digest2, digest.GetDigestSize());
                RsaKeyParameters pub    = new RsaKeyParameters(false, key.AsBigInteger("n"), key.AsBigInteger("e"));

                signer.Init(false, pub);
                signer.BlockUpdate(protectedB64, 0, protectedB64.Length);
                signer.BlockUpdate(rgbDot, 0, 1);
                signer.BlockUpdate(msg.payloadB64, 0, msg.payloadB64.Length);
                if (!signer.VerifySignature(signature))
                {
                    throw new JOSE_Exception("Message failed to verify");
                }
            }

            break;

            case "ES256":
            case "ES384":
            case "ES512": {
                if (key.AsString("kty") != "EC")
                {
                    throw new JOSE_Exception("Wrong Key Type");
                }
                X9ECParameters     p          = NistNamedCurves.GetByName(key.AsString("crv"));
                ECDomainParameters parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H);
                ECPoint            point      = p.Curve.CreatePoint(key.AsBigInteger("x"
                                                                                     ), key.AsBigInteger("y"));
                ECPublicKeyParameters pubKey = new ECPublicKeyParameters(point, parameters);

                ECDsaSigner ecdsa = new ECDsaSigner();
                ecdsa.Init(false, pubKey);

                digest.BlockUpdate(protectedB64, 0, protectedB64.Length);
                digest.BlockUpdate(rgbDot, 0, rgbDot.Length);
                digest.BlockUpdate(msg.payloadB64, 0, msg.payloadB64.Length);
                byte[] o1 = new byte[digest.GetDigestSize()];
                digest.DoFinal(o1, 0);

                BigInteger r = new BigInteger(1, signature, 0, signature.Length / 2);
                BigInteger s = new BigInteger(1, signature, signature.Length / 2, signature.Length / 2);

                if (!ecdsa.VerifySignature(o1, r, s))
                {
                    throw new JOSE_Exception("Signature did not validate");
                }
            }
            break;

            case "HS256":
            case "HS384":
            case "HS512": {
                HMac         hmac = new HMac(digest);
                KeyParameter K    = new KeyParameter(Message.base64urldecode(key.AsString("k")));
                hmac.Init(K);
                hmac.BlockUpdate(protectedB64, 0, protectedB64.Length);
                hmac.BlockUpdate(rgbDot, 0, rgbDot.Length);
                hmac.BlockUpdate(msg.payloadB64, 0, msg.payloadB64.Length);

                byte[] resBuf = new byte[hmac.GetMacSize()];
                hmac.DoFinal(resBuf, 0);

                bool fVerify = true;
                for (int i = 0; i < resBuf.Length; i++)
                {
                    if (resBuf[i] != signature[i])
                    {
                        fVerify = false;
                    }
                }

                if (!fVerify)
                {
                    throw new JOSE_Exception("Signature did not validte");
                }
            }
            break;

            case "EdDSA": {
                ISigner eddsa;
                if (key.AsString("kty") != "OKP")
                {
                    throw new JOSE_Exception("Wrong Key Type");
                }
                switch (key.AsString("crv"))
                {
                case "Ed25519": {
                    Ed25519PublicKeyParameters privKey =
                        new Ed25519PublicKeyParameters(key.AsBytes("X"), 0);
                    eddsa = new Ed25519Signer();
                    eddsa.Init(false, privKey);

                    byte[] toVerify = new byte[protectedB64.Length + rgbDot.Length + msg.payloadB64.Length];
                    Array.Copy(protectedB64, 0, toVerify, 0, protectedB64.Length);
                    Array.Copy(rgbDot, 0, toVerify, protectedB64.Length, rgbDot.Length);
                    Array.Copy(msg.payloadB64, 0, toVerify, protectedB64.Length + rgbDot.Length, msg.payloadB64.Length);

                    eddsa.BlockUpdate(toVerify, 0, toVerify.Length);
                    if (!eddsa.VerifySignature(signature))
                    {
                        throw new JOSE_Exception("Signature did not validate");
                    }

                    break;
                }

                default:
                    throw new JOSE_Exception("Unknown algorithm");
                }

                break;
            }

            default:
                throw new JOSE_Exception("Unknown algorithm");
            }
        }
Exemplo n.º 19
0
        internal bool ValidateMac(byte[] toBeSigned, byte[] signature, string alg)
        {
            IDigest digest;
            IDigest digest2;

            switch (alg)
            {
            case "RS256":
            case "ES256":
            case "PS256":
            case "HS256":
                digest  = new Sha256Digest();
                digest2 = new Sha256Digest();
                break;

            case "RS384":
            case "ES384":
            case "PS384":
            case "HS384":
                digest  = new Sha384Digest();
                digest2 = new Sha384Digest();
                break;

            case "RS512":
            case "ES512":
            case "PS512":
            case "HS512":
                digest  = new Sha512Digest();
                digest2 = new Sha512Digest();
                break;

            case "EdDSA":
                digest  = null;
                digest2 = null;
                break;

            default:
                throw new JoseException("Unknown signature algorithm");
            }


            switch (alg)
            {
            case "RS256":
            case "RS384":
            case "RS512": {
                if (this.AsString("kty") != "RSA")
                {
                    throw new JoseException("Wrong Key");
                }
                RsaDigestSigner  signer = new RsaDigestSigner(digest);
                RsaKeyParameters pub    = new RsaKeyParameters(false, this.AsBigInteger("n"), this.AsBigInteger("e"));

                signer.Init(false, pub);
                signer.BlockUpdate(toBeSigned, 0, toBeSigned.Length);
                if (!signer.VerifySignature(signature))
                {
                    throw new JoseException("Message failed to verify");
                }
            }
            break;

            case "PS256":
            case "PS384":
            case "PS512": {
                PssSigner        signer = new PssSigner(new RsaEngine(), digest, digest2, digest2.GetDigestSize());
                RsaKeyParameters pub    = new RsaKeyParameters(false, this.AsBigInteger("n"), this.AsBigInteger("e"));

                signer.Init(false, pub);
                signer.BlockUpdate(toBeSigned, 0, toBeSigned.Length);
                if (!signer.VerifySignature(signature))
                {
                    throw new JoseException("Message failed to verify");
                }
            }

            break;

            case "ES256":
            case "ES384":
            case "ES512": {
                digest.BlockUpdate(toBeSigned, 0, toBeSigned.Length);
                byte[] o1 = new byte[digest.GetDigestSize()];
                digest.DoFinal(o1, 0);

                if (this.AsString("kty") != "EC")
                {
                    throw new JoseException("Wrong Key Type");
                }

                ICipherParameters pubKey = this.AsPublicKey();
                ECDsaSigner       ecdsa  = new ECDsaSigner();
                ecdsa.Init(false, pubKey);

                BigInteger r = new BigInteger(1, signature, 0, signature.Length / 2);
                BigInteger s = new BigInteger(1, signature, signature.Length / 2, signature.Length / 2);

                if (!ecdsa.VerifySignature(o1, r, s))
                {
                    throw new JoseException("Signature did not validate");
                }
            }
            break;

            case "HS256":
            case "HS384":
            case "HS512": {
                HMac         hmac = new HMac(digest);
                KeyParameter K    = new KeyParameter(Message.base64urldecode(this.AsString("k")));
                hmac.Init(K);
                hmac.BlockUpdate(toBeSigned, 0, toBeSigned.Length);

                byte[] resBuf = new byte[hmac.GetMacSize()];
                hmac.DoFinal(resBuf, 0);

                bool fVerify = true;
                for (int i = 0; i < resBuf.Length; i++)
                {
                    if (resBuf[i] != signature[i])
                    {
                        fVerify = false;
                    }
                }

                if (!fVerify)
                {
                    throw new JoseException("Signature did not validate");
                }
            }
            break;

            case "EdDSA": {
                ISigner eddsa;
                if (this.AsString("kty") != "OKP")
                {
                    throw new JoseException("Wrong Key Type");
                }
                switch (this.AsString("crv"))
                {
                case "Ed25519": {
                    Ed25519PublicKeyParameters privKey =
                        new Ed25519PublicKeyParameters(this.AsBytes("X"), 0);
                    eddsa = new Ed25519Signer();
                    eddsa.Init(false, privKey);

                    eddsa.BlockUpdate(toBeSigned, 0, toBeSigned.Length);
                    if (!eddsa.VerifySignature(signature))
                    {
                        throw new JoseException("Signature did not validate");
                    }

                    break;
                }

                default:
                    throw new JoseException("Unknown algorithm");
                }

                break;
            }

            default:
                throw new JoseException("Unknown algorithm");
            }

            return(true);
        }
Exemplo n.º 20
0
        public bool Verify(SignMessage msg)
        {
            string alg = FindAttribute("alg").AsString();

            JWK key = keyToSign;

            IDigest digest;
            IDigest digest2;

            switch (alg)
            {
            case "RS256":
            case "ES256":
            case "PS256":
            case "HS256":
                digest  = new Sha256Digest();
                digest2 = new Sha256Digest();
                break;

            case "RS384":
            case "ES384":
            case "PS384":
            case "HS384":
                digest  = new Sha384Digest();
                digest2 = new Sha384Digest();
                break;

            case "RS512":
            case "ES512":
            case "PS512":
            case "HS512":
                digest  = new Sha512Digest();
                digest2 = new Sha512Digest();
                break;

            case "EdDSA":
                digest  = null;
                digest2 = null;
                break;

            default:
                throw new JoseException("Unknown signature algorithm");
            }

            //

            byte[] toBeSigned;
            string str  = "";
            string body = Encoding.UTF8.GetString(msg.payloadB64);

            if (ProtectedMap.ContainsKey("b64") && ProtectedMap["b64"].AsBoolean() == false)
            {
                str += protectedB64 + "." + body;
            }
            else
            {
                str += protectedB64 + "." + body;
            }

            toBeSigned = Encoding.UTF8.GetBytes(str);


            switch (alg)
            {
            case "RS256":
            case "RS384":
            case "RS512": {
                if (key.AsString("kty") != "RSA")
                {
                    throw new JoseException("Wrong Key");
                }
                RsaDigestSigner  signer = new RsaDigestSigner(digest);
                RsaKeyParameters pub    = new RsaKeyParameters(false, key.AsBigInteger("n"), key.AsBigInteger("e"));

                signer.Init(false, pub);
                signer.BlockUpdate(toBeSigned, 0, toBeSigned.Length);
                if (!signer.VerifySignature(signature))
                {
                    throw new JoseException("Message failed to verify");
                }
            }
            break;

            case "PS256":
            case "PS384":
            case "PS512": {
                PssSigner        signer = new PssSigner(new RsaEngine(), digest, digest2, digest2.GetDigestSize());
                RsaKeyParameters pub    = new RsaKeyParameters(false, key.AsBigInteger("n"), key.AsBigInteger("e"));

                signer.Init(false, pub);
                signer.BlockUpdate(toBeSigned, 0, toBeSigned.Length);
                if (!signer.VerifySignature(signature))
                {
                    throw new JoseException("Message failed to verify");
                }
            }

            break;

            case "ES256":
            case "ES384":
            case "ES512": {
                digest.BlockUpdate(toBeSigned, 0, toBeSigned.Length);
                byte[] o1 = new byte[digest.GetDigestSize()];
                digest.DoFinal(o1, 0);

                if (key.AsString("kty") != "EC")
                {
                    throw new JoseException("Wrong Key Type");
                }

                ICipherParameters pubKey = keyToSign.AsPublicKey();
                ECDsaSigner       ecdsa  = new ECDsaSigner();
                ecdsa.Init(false, pubKey);

                BigInteger r = new BigInteger(1, signature, 0, signature.Length / 2);
                BigInteger s = new BigInteger(1, signature, signature.Length / 2, signature.Length / 2);

                if (!ecdsa.VerifySignature(o1, r, s))
                {
                    throw new JoseException("Signature did not validate");
                }
            }
            break;

            case "HS256":
            case "HS384":
            case "HS512": {
                HMac         hmac = new HMac(digest);
                KeyParameter K    = new KeyParameter(Message.base64urldecode(key.AsString("k")));
                hmac.Init(K);
                hmac.BlockUpdate(toBeSigned, 0, toBeSigned.Length);

                byte[] resBuf = new byte[hmac.GetMacSize()];
                hmac.DoFinal(resBuf, 0);

                bool fVerify = true;
                for (int i = 0; i < resBuf.Length; i++)
                {
                    if (resBuf[i] != signature[i])
                    {
                        fVerify = false;
                    }
                }

                if (!fVerify)
                {
                    throw new JoseException("Signature did not validate");
                }
            }
            break;

            case "EdDSA": {
                ISigner eddsa;
                if (key.AsString("kty") != "OKP")
                {
                    throw new JoseException("Wrong Key Type");
                }
                switch (key.AsString("crv"))
                {
                case "Ed25519": {
                    Ed25519PublicKeyParameters privKey =
                        new Ed25519PublicKeyParameters(key.AsBytes("X"), 0);
                    eddsa = new Ed25519Signer();
                    eddsa.Init(false, privKey);

                    eddsa.BlockUpdate(toBeSigned, 0, toBeSigned.Length);
                    if (!eddsa.VerifySignature(signature))
                    {
                        throw new JoseException("Signature did not validate");
                    }

                    break;
                }

                default:
                    throw new JoseException("Unknown algorithm");
                }

                break;
            }

            default:
                throw new JoseException("Unknown algorithm");
            }

            return(true);
        }