private static string Decrypt(byte[][] parts, object key) { byte[] header = parts[0]; byte[] encryptedCek = parts[1]; byte[] iv = parts[2]; byte[] cipherText = parts[3]; byte[] authTag = parts[4]; IDictionary <string, object> jwtHeader = jsMapper.Parse <Dictionary <string, object> >(Encoding.UTF8.GetString(header, 0, header.Length)); IKeyManagement keys = KeyAlgorithms[GetJweAlgorithm((string)jwtHeader["alg"])]; IJweAlgorithm enc = EncAlgorithms[GetJweEncryption((string)jwtHeader["enc"])]; byte[] cek = keys.Unwrap(encryptedCek, key, enc.KeySize, jwtHeader); byte[] aad = Encoding.UTF8.GetBytes(Compact.Serialize(header)); byte[] plainText = enc.Decrypt(aad, cek, iv, cipherText, authTag); if (jwtHeader.ContainsKey("zip")) { plainText = CompressionAlgorithms[GetJweCompression((string)jwtHeader["zip"])].Decompress(plainText); } return(Encoding.UTF8.GetString(plainText, 0, plainText.Length)); }
private static byte[] DecryptBytes(byte[][] parts, object key, JweAlgorithm?jweAlg, JweEncryption?jweEnc) { byte[] numArray = parts[0]; byte[] numArray1 = parts[1]; byte[] numArray2 = parts[2]; byte[] numArray3 = parts[3]; byte[] numArray4 = parts[4]; IDictionary <string, object> strs = JWT.jsMapper.Parse <Dictionary <string, object> >(Encoding.UTF8.GetString(numArray)); IKeyManagement item = JWT.KeyAlgorithms[JWT.GetJweAlgorithm((string)strs["alg"])]; IJweAlgorithm jweAlgorithm = JWT.EncAlgorithms[JWT.GetJweEncryption((string)strs["enc"])]; if (jweAlg.HasValue && jweAlg.Value != JWT.GetJweAlgorithm((string)strs["alg"])) { throw new InvalidAlgorithmException("The algorithm type passed to the Decrypt method did not match the algorithm type in the header."); } if (jweEnc.HasValue && jweEnc.Value != JWT.GetJweEncryption((string)strs["enc"])) { throw new InvalidAlgorithmException("The encryption type passed to the Decrypt method did not match the encryption type in the header."); } byte[] numArray5 = item.Unwrap(numArray1, key, jweAlgorithm.KeySize, strs); byte[] bytes = Encoding.UTF8.GetBytes(Compact.Serialize(new byte[][] { numArray })); byte[] numArray6 = jweAlgorithm.Decrypt(bytes, numArray5, numArray2, numArray3, numArray4); if (strs.ContainsKey("zip")) { numArray6 = JWT.CompressionAlgorithms[JWT.GetJweCompression((string)strs["zip"])].Decompress(numArray6); } return(numArray6); }
private static byte[] DecryptBytes(byte[][] parts, object key, JweAlgorithm?jweAlg, JweEncryption?jweEnc) { byte[] header = parts[0]; byte[] encryptedCek = parts[1]; byte[] iv = parts[2]; byte[] cipherText = parts[3]; byte[] authTag = parts[4]; IDictionary <string, object> jwtHeader = jsMapper.Parse <Dictionary <string, object> >(Encoding.UTF8.GetString(header)); IKeyManagement keys = KeyAlgorithms[GetJweAlgorithm((string)jwtHeader["alg"])]; IJweAlgorithm enc = EncAlgorithms[GetJweEncryption((string)jwtHeader["enc"])]; if (jweAlg != null && (JweAlgorithm)jweAlg != GetJweAlgorithm((string)jwtHeader["alg"])) { throw new InvalidAlgorithmException("The algorithm type passed to the Decrypt method did not match the algorithm type in the header."); } if (jweEnc != null && (JweEncryption)jweEnc != GetJweEncryption((string)jwtHeader["enc"])) { throw new InvalidAlgorithmException("The encryption type passed to the Decrypt method did not match the encryption type in the header."); } byte[] cek = keys.Unwrap(encryptedCek, key, enc.KeySize, jwtHeader); byte[] aad = Encoding.UTF8.GetBytes(Compact.Serialize(header)); byte[] plainText = enc.Decrypt(aad, cek, iv, cipherText, authTag); if (jwtHeader.ContainsKey("zip")) { plainText = CompressionAlgorithms[GetJweCompression((string)jwtHeader["zip"])].Decompress(plainText); } return(plainText); }
private static byte[] DecryptBytes(byte[][] parts, object key, JweAlgorithm?jweAlg, JweEncryption?jweEnc, JwtSettings settings = null) { byte[] header = parts[0]; byte[] encryptedCek = parts[1]; byte[] iv = parts[2]; byte[] cipherText = parts[3]; byte[] authTag = parts[4]; JwtSettings jwtSettings = GetSettings(settings); IDictionary <string, object> jwtHeader = jwtSettings.JsonMapper.Parse <Dictionary <string, object> >(Encoding.UTF8.GetString(header)); JweAlgorithm headerAlg = jwtSettings.JwaAlgorithmFromHeader((string)jwtHeader["alg"]); JweEncryption headerEnc = jwtSettings.JweAlgorithmFromHeader((string)jwtHeader["enc"]); IKeyManagement keys = jwtSettings.Jwa(headerAlg); IJweAlgorithm enc = jwtSettings.Jwe(headerEnc); if (keys == null) { throw new JoseException(string.Format("Unsupported JWA algorithm requested: {0}", headerAlg)); } if (enc == null) { throw new JoseException(string.Format("Unsupported JWE algorithm requested: {0}", headerEnc)); } if (jweAlg != null && (JweAlgorithm)jweAlg != headerAlg) { throw new InvalidAlgorithmException("The algorithm type passed to the Decrypt method did not match the algorithm type in the header."); } if (jweEnc != null && (JweEncryption)jweEnc != headerEnc) { throw new InvalidAlgorithmException("The encryption type passed to the Decrypt method did not match the encryption type in the header."); } byte[] cek = keys.Unwrap(encryptedCek, key, enc.KeySize, jwtHeader); byte[] aad = Encoding.UTF8.GetBytes(Compact.Serialize(header)); byte[] plainText = enc.Decrypt(aad, cek, iv, cipherText, authTag); if (jwtHeader.ContainsKey("zip")) { var alg = (string)jwtHeader["zip"]; var compression = jwtSettings.Compression(GetJweCompression(alg)); if (compression == null) { throw new JoseException(string.Format("Unsupported compressions algorithm requested: {0}", alg)); } plainText = compression.Decompress(plainText); } return(plainText); }
/// <summary> /// Decypts a JWE by performing necessary decompression/decryption and authenticated decryption as defined in RFC7516. /// </summary> /// <param name="jwe">JWE to decrypt.</param> /// <param name="key">key for decoding suitable for JWE algorithm used to encrypt the CEK.</param> /// <param name="expectedJweAlg">The algorithm type that we expect to receive in the header.</param> /// <param name="expectedJweEnc">The encryption type that we expect to receive in the header.</param> /// <param name="settings">optional settings to override global DefaultSettings</param> /// <returns>Decrypted JweToken object</returns> /// <exception cref="IntegrityException">if AEAD operation validation failed</exception> /// <exception cref="EncryptionException">if JWE can't be decrypted</exception> /// <exception cref="InvalidAlgorithmException">if encryption or compression algorithm is not supported</exception> public static JweToken Decrypt(string jwe, object key, JweAlgorithm?expectedJweAlg = null, JweEncryption?expectedJweEnc = null, JwtSettings settings = null) { Ensure.IsNotEmpty(jwe, "Incoming jwe expected to be in a valid serialization form, not empty, whitespace or null."); settings = GetSettings(settings); JweToken token = Headers(jwe); if (token.ProtectedHeaderBytes == null && token.Encoding == SerializationMode.Compact) { throw new JoseException(string.Format("Protected header was missing but required with compact encoding.")); } var exceptions = new List <Exception>(); foreach (var recipient in token.Recipients) { var headerAlg = settings.JwaAlgorithmFromHeader((string)recipient.JoseHeader["alg"]); var encryptedCek = recipient.EncryptedCek; // skip recipient if asked to do strict validation if (expectedJweAlg != null && expectedJweAlg != headerAlg) { continue; } IKeyManagement keys = settings.Jwa(headerAlg); if (keys == null) { throw new JoseException(string.Format("Unsupported JWA algorithm requested: {0}", headerAlg)); } try { JweEncryption headerEnc = settings.JweAlgorithmFromHeader((string)recipient.JoseHeader["enc"]); IJweAlgorithm enc = settings.Jwe(headerEnc); if (enc == null) { throw new JoseException(string.Format("Unsupported JWE algorithm requested: {0}", headerEnc)); } if (expectedJweEnc != null && expectedJweEnc != headerEnc) { throw new InvalidAlgorithmException("The encryption type passed to the Decrypt method did not match the encryption type in the header."); } byte[] cek = keys.Unwrap(recipient.EncryptedCek, key, enc.KeySize, recipient.JoseHeader); byte[] plaintext = enc.Decrypt(Aad(token.ProtectedHeaderBytes, token.Aad), cek, token.Iv, token.Ciphertext, token.AuthTag); if (recipient.JoseHeader.TryGetValue("zip", out var compressionAlg)) { var compression = settings.Compression((string)compressionAlg); plaintext = compression.Decompress(plaintext); } token.PlaintextBytes = plaintext; token.Recipient = recipient; return(token); } catch (ArgumentException ex) { exceptions.Add(ex); } catch (JoseException ex) { exceptions.Add(ex); } } // nobody was eligable for decryption if (exceptions.Count == 0) { throw new InvalidAlgorithmException("The algorithm type passed to the Decrypt method did not match the algorithm type in the header."); } // decryption failed if (exceptions.Select(e => new KeyValuePair <Type, String>(e.GetType(), e.Message)).Distinct().Count() == 1) { // throw the first throw exceptions[0]; } else { throw new JoseException($"No recipients able to decrypt.", new AggregateException(exceptions)); } }
/// <summary> /// Decypts a JWE by performing necessary decompression/decryption and authenticated decryption as defined in RFC7516. /// </summary> /// <param name="jwe">JWE to decrypt.</param> /// <param name="key">key for decoding suitable for JWE algorithm used to encrypt the CEK.</param> /// <param name="expectedJweAlg">The algorithm type that we expect to receive in the header.</param> /// <param name="expectedJweEnc">The encryption type that we expect to receive in the header.</param> /// <param name="settings">optional settings to override global DefaultSettings</param> /// <returns>Decrypted plaintext as binary data</returns> /// <exception cref="IntegrityException">if AEAD operation validation failed</exception> /// <exception cref="EncryptionException">if JWE can't be decrypted</exception> /// <exception cref="InvalidAlgorithmException">if encryption or compression algorithm is not supported</exception> public static (byte[] Plaintext, IDictionary <string, object> JoseHeaders, byte[] Aad) Decrypt(string jwe, object key, JweAlgorithm?expectedJweAlg = null, JweEncryption?expectedJweEnc = null, JwtSettings settings = null) { Ensure.IsNotEmpty(jwe, "Incoming jwe expected to be in a valid serialization form, not empty, whitespace or null."); settings = GetSettings(settings); ParsedJwe parsedJwe = ParsedJwe.Parse(jwe, settings); IDictionary <string, object> protectedHeader = settings.JsonMapper.Parse <Dictionary <string, object> >( Encoding.UTF8.GetString(parsedJwe.ProtectedHeaderBytes)); if (protectedHeader == null && parsedJwe.Encoding == SerializationMode.Compact) { throw new JoseException(string.Format("Protected header was missing but required with compact encoding.")); } IJweAlgorithm enc = null; /* * if (protectedHeader != null) * { * JweEncryption headerEnc = settings.JweAlgorithmFromHeader((string)protectedHeader["enc"]); * enc = settings.Jwe(headerEnc); * * if (enc == null && parsedJwe.Encoding == SerializationMode.Compact) * { * throw new JoseException(string.Format("Unsupported JWE algorithm requested: {0}", headerEnc)); * } * * if (expectedJweEnc != null && expectedJweEnc != headerEnc && parsedJwe.Encoding == SerializationMode.Compact) * { * throw new InvalidAlgorithmException("The encryption type passed to the Decrypt method did not match the encryption type in the header."); * } * } */ var algMatchingRecipients = parsedJwe.Recipients.Select(r => { var joseHeader = Dictionaries.MergeHeaders(protectedHeader, parsedJwe.UnprotectedHeader, r.Header); return(new { JoseHeader = joseHeader, HeaderAlg = settings.JwaAlgorithmFromHeader((string)joseHeader["alg"]), EncryptedCek = r.EncryptedCek, }); }) .Where(r => (expectedJweAlg == null || expectedJweAlg == r.HeaderAlg)); if (!algMatchingRecipients.Any()) { throw new InvalidAlgorithmException("The algorithm type passed to the Decrypt method did not match the algorithm type in the header."); } var exceptions = new List <Exception>(); foreach (var recipient in algMatchingRecipients) { IKeyManagement keys = settings.Jwa(recipient.HeaderAlg); if (keys == null) { throw new JoseException(string.Format("Unsupported JWA algorithm requested: {0}", recipient.HeaderAlg)); } try { JweEncryption headerEnc = settings.JweAlgorithmFromHeader((string)recipient.JoseHeader["enc"]); enc = settings.Jwe(headerEnc); if (enc == null) { throw new JoseException(string.Format("Unsupported JWE algorithm requested: {0}", headerEnc)); } if (expectedJweEnc != null && expectedJweEnc != headerEnc) { throw new InvalidAlgorithmException("The encryption type passed to the Decrypt method did not match the encryption type in the header."); } byte[] cek = keys.Unwrap(recipient.EncryptedCek, key, enc.KeySize, recipient.JoseHeader); byte[] asciiEncodedProtectedHeader = Encoding.ASCII.GetBytes(Base64Url.Encode(parsedJwe.ProtectedHeaderBytes)); byte[] aad = parsedJwe.Aad == null? Encoding.ASCII.GetBytes(Base64Url.Encode(parsedJwe.ProtectedHeaderBytes)) : Encoding.ASCII.GetBytes(string.Concat(Base64Url.Encode(parsedJwe.ProtectedHeaderBytes), ".", Base64Url.Encode(parsedJwe.Aad))); byte[] plaintext = enc.Decrypt(aad, cek, parsedJwe.Iv, parsedJwe.Ciphertext, parsedJwe.AuthTag); if (recipient.JoseHeader.TryGetValue("zip", out var compressionAlg)) { var compression = settings.Compression((string)compressionAlg); plaintext = compression.Decompress(plaintext); } return(Plaintext : plaintext, JoseHeaders : recipient.JoseHeader, Aad : parsedJwe.Aad); } catch (ArgumentException ex) { exceptions.Add(ex); } catch (JoseException ex) { exceptions.Add(ex); } } if (exceptions.Select(e => (e.GetType(), e.Message)).Distinct().Count() == 1) { // throw the first throw exceptions[0]; }