private void ECDH_GenerateEphemeral(EncryptMessage msg) { CBORObject epk = CBORObject.NewMap(); if (_mKey.AsString("kty") == "EC") { X9ECParameters p = NistNamedCurves.GetByName(_mKey.AsString("crv")); ECDomainParameters parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H); ECKeyPairGenerator pGen = new ECKeyPairGenerator(); ECKeyGenerationParameters genParam = new ECKeyGenerationParameters(parameters, Message.s_PRNG); pGen.Init(genParam); AsymmetricCipherKeyPair p1 = pGen.GenerateKeyPair(); epk.Add("kty", "EC"); epk.Add("crv", _mKey.AsString("crv")); ECPublicKeyParameters priv = (ECPublicKeyParameters)p1.Public; epk.Add("x", priv.Q.Normalize().XCoord.ToBigInteger().ToByteArrayUnsigned()); epk.Add("y", priv.Q.Normalize().YCoord.ToBigInteger().ToByteArrayUnsigned()); } else if (_mKey.AsString("kty") == "OKP") { switch (_mKey.AsString("crv")) { case "X25519": Ed25519KeyPairGenerator pGen = new Ed25519KeyPairGenerator(); Ed25519KeyGenerationParameters genParam = new Ed25519KeyGenerationParameters(Message.s_PRNG); pGen.Init(genParam); AsymmetricCipherKeyPair p1 = pGen.GenerateKeyPair(); Ed25519PublicKeyParameters pub = (Ed25519PublicKeyParameters)p1.Public; epk.Add("kty", "OKP"); epk.Add("crv", "X25519"); epk.Add("x", pub.GetEncoded()); break; default: throw new JoseException("Unknown OPK curve"); } } else { throw new JoseException("Internal Error"); } if (msg.FindAttribute(CBORObject.FromObject("epk"), PROTECTED) != null) { msg.AddAttribute(CBORObject.FromObject("epk"), epk, PROTECTED); } else if (msg.FindAttribute(CBORObject.FromObject("epk"), PROTECTED) != null) { msg.AddAttribute(CBORObject.FromObject("epk"), epk, PROTECTED); } else { AddAttribute("epk", epk, UNPROTECTED); } }
private byte[] Ecdh(JWK key, EncryptMessage msg) { if ((key.AsString("kty") != "EC") && (key.AsString("kty") != "OKP")) { throw new JoseException("Not an EC or OKP Key"); } CBORObject epkT = FindAttribute("epk"); if (epkT == null) { epkT = msg.FindAttribute("epk"); if (epkT == null) { throw new JoseException("No Ephemeral key"); } } JWK epk = new JWK(epkT); if (epk.AsString("crv") != key.AsString("crv")) { throw new JoseException("not a match of curves"); } // Get the curve if (key.AsString("kty") == "EC") { 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"); } } }
private void AES_GCM_KeyWrap(int keySize, EncryptMessage msg) { if (_mKey.AsString("kty") != "oct") { throw new JoseException("Incorrect key type"); } byte[] keyBytes = _mKey.AsBytes("k"); if (keyBytes.Length != keySize / 8) { throw new JoseException("Key is not the correct size"); } GcmBlockCipher cipher = new GcmBlockCipher(new AesEngine(), new BasicGcmMultiplier()); KeyParameter contentKey; // The requirements from JWA // IV is 96 bits // Authentication tag is 128 bits // key sizes are 128, 192 and 256 bits // Keywrap says that there is no AAD contentKey = new KeyParameter(keyBytes); byte[] a = new byte[0]; byte[] iv = new byte[96 / 8]; Message.s_PRNG.NextBytes(iv); if (msg.FindAttribute(CBORObject.FromObject("iv"), PROTECTED) != null) { msg.AddAttribute("iv", Message.base64urlencode(iv), PROTECTED); } else if (msg.FindAttribute(CBORObject.FromObject("iv"), UNPROTECTED) != null) { msg.AddAttribute("iv", Message.base64urlencode(iv), UNPROTECTED); } else { UnprotectedMap.Add("iv", Message.base64urlencode(iv)); } AeadParameters parameters = new AeadParameters(contentKey, 128, iv, a); cipher.Init(true, parameters); byte[] c = new byte[cipher.GetOutputSize(_payload.Length)]; int len = cipher.ProcessBytes(_payload, 0, _payload.Length, c, 0); len += cipher.DoFinal(c, len); if (len != c.Length) { throw new JoseException("NYI"); } byte[] tag = new byte[128 / 8]; Array.Copy(c, c.Length - tag.Length, tag, 0, tag.Length); if (msg.FindAttribute(CBORObject.FromObject("tag"), PROTECTED) != null) { msg.AddAttribute("tag", Message.base64urlencode(tag), PROTECTED); } else if (msg.FindAttribute(CBORObject.FromObject("tag"), UNPROTECTED) != null) { msg.AddAttribute("tag", Message.base64urlencode(tag), UNPROTECTED); } else { UnprotectedMap.Add("tag", Message.base64urlencode(tag)); } _rgbEncrypted = c; Array.Resize(ref _rgbEncrypted, c.Length - tag.Length); }