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 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); }