示例#1
0
        private void RSA_1_5_KeyWrap()
        {
            IAsymmetricBlockCipher cipher        = new Pkcs1Encoding(new RsaEngine());
            RsaKeyParameters       pubParameters = new RsaKeyParameters(false, _mKey.AsBigInteger("n"), _mKey.AsBigInteger("e"));

            cipher.Init(true, new ParametersWithRandom(pubParameters, Message.s_PRNG));

            byte[] outBytes = cipher.ProcessBlock(_payload, 0, _payload.Length);

            _rgbEncrypted = outBytes;
        }
示例#2
0
        private byte[] ECDH_GenerateSecret(JWK key, EncryptMessage msg)
        {
            JWK epk;

            if ((key.AsString("kty") != "EC") && (key.AsString("kty") != "OKP"))
            {
                throw new JoseException("Not an EC or OKP Key");
            }

            if (_mSenderKey != null)
            {
                epk = _mSenderKey;
            }
            else
            {
                CBORObject epkT = FindAttr("epk", msg);
                if (epkT == null)
                {
                    throw new JoseException("No Ephemeral key");
                }
                epk = new JWK(epkT);
            }

            if (epk.AsString("crv") != key.AsString("crv"))
            {
                throw new JoseException("not a match of curves");
            }

            if (key.AsString("kty") == "EC")
            {
                //  Get the curve

                X9ECParameters     p          = NistNamedCurves.GetByName(key.AsString("crv"));
                ECDomainParameters parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H);

                Org.BouncyCastle.Math.EC.ECPoint pubPoint = p.Curve.CreatePoint(epk.AsBigInteger("x"), epk.AsBigInteger("y"));
                ECPublicKeyParameters            pub      = new ECPublicKeyParameters(pubPoint, parameters);

                ECPrivateKeyParameters priv = new ECPrivateKeyParameters(key.AsBigInteger("d"), parameters);

                IBasicAgreement e1 = new ECDHBasicAgreement();
                e1.Init(priv);

                BigInteger k1 = e1.CalculateAgreement(pub);

                return(k1.ToByteArrayUnsigned());
            }
            else
            {
                switch (epk.AsString("crv"))
                {
                case "X25519": {
                    X25519PublicKeyParameters pub =
                        new X25519PublicKeyParameters(epk.AsBytes("x"), 0);
                    X25519PrivateKeyParameters priv =
                        new X25519PrivateKeyParameters(key.AsBytes("d"), 0);

                    X25519Agreement agree = new X25519Agreement();
                    agree.Init(priv);
                    byte[] secret = new byte[32];
                    agree.CalculateAgreement(pub, secret, 0);
                    return(secret);
                }

                default:
                    throw new JoseException("Unsupported curve");
                }
            }
        }
示例#3
0
        public byte[] Decrypt(int cbitKey, EncryptMessage msg)
        {
            JWK key = _mKey;

            if (key == null)
            {
                throw new JoseException("No key specified.");
            }
            string alg;

            alg = FindAttr("alg", msg).AsString();

            switch (alg)
            {
            case "dir":
                if (key.AsString("kty") != "oct")
                {
                    return(null);
                }
                return(key.AsBytes("k"));

            case "ECDH-ES": {
                if ((key.AsString("kty") != "EC") && (key.AsString("kty") != "OKP"))
                {
                    return(null);
                }

                byte[] secret = Ecdh(key, msg);
                byte[] kwKey  = Kdf(secret, msg, cbitKey, FindAttr("enc", msg).AsString());
                return(kwKey);
            }

            case "A128KW":
            case "A192KW":
            case "A256KW":
                if (key.AsString("kty") != "oct")
                {
                    return(null);
                }

                return(AES_KeyWrap(key.AsBytes("k")));

            case "A128GCMKW":
            case "A192GCMKW":
            case "A256GCMKW":
                if (key.AsString("kty") != "oct")
                {
                    return(null);
                }
                return(AESGCM_KeyWrap(key.AsBytes("k"), msg));

            case "PBES2-HS256+A128KW":
            case "PBES2-HS384+A192KW":
            case "PBES2-HS512+A256KW": {
                if (key.AsString("kty") != "oct")
                {
                    return(null);
                }
                byte[] saltInput = Message.base64urldecode(FindAttr("p2s", msg).AsString());
                byte[] algBytes  = Encoding.UTF8.GetBytes(alg);
                byte[] salt      = new byte[alg.Length + 1 + saltInput.Length];
                Array.Copy(algBytes, salt, algBytes.Length);
                Array.Copy(saltInput, 0, salt, algBytes.Length + 1, saltInput.Length);
                int iterCount = FindAttr("p2c", msg).AsInt32();

                byte[] rgbSecret = PBKDF2(key.AsBytes("k"), salt, iterCount, 256 / 8, new Sha512Digest());

                return(AES_KeyWrap(rgbSecret));
            }

            case "RSA-OAEP-256":
            case "RSA-OAEP": {
                IAsymmetricBlockCipher cipher = new OaepEncoding(new RsaEngine(), alg == "RSA-OAEP" ? (IDigest) new Sha1Digest() : new Sha256Digest());
                RsaKeyParameters       prv    = new RsaPrivateCrtKeyParameters(key.AsBigInteger("n"), key.AsBigInteger("e"), key.AsBigInteger("d"), key.AsBigInteger("p"), key.AsBigInteger("q"),
                                                                               key.AsBigInteger("dp"), key.AsBigInteger("dq"), key.AsBigInteger("qi"));

                cipher.Init(false, prv);
                byte[] outBytes = cipher.ProcessBlock(_rgbEncrypted, 0, _rgbEncrypted.Length);

                return(outBytes);
            }

            case "ECDH-ES+A128KW": {
                if ((key.AsString("kty") != "EC") && (key.AsString("kty") != "OKP"))
                {
                    return(null);
                }

                byte[] secret = Ecdh(key, msg);
                byte[] kwKey  = Kdf(secret, msg, 128, FindAttr("alg", msg).AsString());
                return(AES_KeyWrap(kwKey));
            }

            case "ECDH-ES+A192KW": {
                if (key.AsString("kty") != "EC")
                {
                    return(null);
                }

                byte[] secret = Ecdh(key, msg);
                byte[] kwKey  = Kdf(secret, msg, 192, FindAttr("alg", msg).AsString());
                return(AES_KeyWrap(kwKey));
            }

            case "ECDH-ES+A256KW": {
                if (key.AsString("kty") != "EC")
                {
                    return(null);
                }

                byte[] secret = Ecdh(key, msg);
                byte[] kwKey  = Kdf(secret, msg, 256, FindAttr("alg", msg).AsString());
                return(AES_KeyWrap(kwKey));
            }

            case "RSA1_5": {
                if (key.AsString("kty") != "RSA")
                {
                    return(null);
                }

                IAsymmetricBlockCipher cipher = new Pkcs1Encoding(new RsaEngine());
                RsaKeyParameters       prv    = new RsaPrivateCrtKeyParameters(key.AsBigInteger("n"), key.AsBigInteger("e"), key.AsBigInteger("d"), key.AsBigInteger("p"), key.AsBigInteger("q"),
                                                                               key.AsBigInteger("dp"), key.AsBigInteger("dq"), key.AsBigInteger("qi"));

                cipher.Init(false, prv);
                return(cipher.ProcessBlock(_rgbEncrypted, 0, _rgbEncrypted.Length));
            }
            }

            return(null);
        }
示例#4
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);
        }