public static String FromJWTBase64(String serializedJWT, ILogger logger, ISecurityVault securityVault, String issuer, String symPWSecretName, String symSaltSecretName, String receiverPrivateKeyName, String senderPublicKeyName) { IJWTService jwtService = new RSAJWTService(); var symCryptoKey = SymmetricCryptoService.CreateSymmetricKey(securityVault.GetSecret(symPWSecretName), securityVault.GetSecret(symSaltSecretName)); var rsaPrivateKeySet2Contents = securityVault.GetSecret(receiverPrivateKeyName); var rsaPublicKeySet1Contents = securityVault.GetSecret(senderPublicKeyName); var validationParameters = getValidationParameters(issuer); var jwtIsValid = jwtService.ValidateJWTRSA(serializedJWT, rsaPublicKeySet1Contents, "RS256", validationParameters); // Senders public key Console.WriteLine($"JWT is valid:{jwtIsValid}"); if (!jwtIsValid) { throw new Exception("Invalid JWT signature"); } // Decoding if sinature is valid var jwtReread = jwtService.ReadJWTRSA(serializedJWT, rsaPublicKeySet1Contents, "RS256", validationParameters); // Senders public key Console.WriteLine($"serializedJWTReread:{jwtReread}"); var encrypteddData = jwtReread.Payload.Claims.Where(c => c.Type == "sym_encrypted_data").Single().Value; // Assuming that it always has data var encrypteddKeyBase64 = jwtReread.Payload.Claims.Where(c => c.Type == "encrypted_key_bas64").Single().Value; // Assuming that it always has data var encrypteddIVBase64 = jwtReread.Payload.Claims.Where(c => c.Type == "encrypted_iv_bas64").Single().Value; // Assuming that it always has data // Note: The private key from set2 should only be held by opposing party, and never exchanged, as with all private keys var symKeyBase64 = jwtService.Decrypt(encrypteddKeyBase64, rsaPrivateKeySet2Contents); // Receivers private key var symIVBase64 = jwtService.Decrypt(encrypteddIVBase64, rsaPrivateKeySet2Contents); // Receivers private key var symKey = Convert.FromBase64String(symKeyBase64); var symIV = Convert.FromBase64String(symIVBase64); var decryptedData = SymmetricCryptoService.Decrypt(encrypteddData, symKey, symIV); Console.WriteLine($"Decrypted data reread:{decryptedData}"); return(decryptedData); }
private static void SimulateReceiver() { var simpleMessage = GetRequest(); IJWTService jwtService = new RSAJWTService(); var rsaPrivateKeySet2Contents = File.ReadAllText($@"{LocalFileStorePath}\keys\rsa-prv-key-set2.key"); // Checking if JWT signature is valid var validationParameters = BuildValidationParameters(); var receivedJWT = simpleMessage.AuthorizationHeader; var receivedContent = simpleMessage.BodyContents; var jwtIsValid = jwtService.ValidateJWTRSA(receivedJWT, RSAPublicKeySet1Contents, "RS256", validationParameters); // Senders public key Console.WriteLine($"JWT validation={jwtIsValid}"); // Decoding if sinature is valid var jwtReread = jwtService.ReadJWTRSA(receivedJWT, RSAPublicKeySet1Contents, "RS256", validationParameters); // Senders public key Console.WriteLine($"serializedJWTReread:{jwtReread}"); var contentHashBase64 = jwtReread.Payload.Claims.Where(c => c.Type == "content_hash_base64").Single().Value; // Assuming that it always has data var contentHashAlgorithm = jwtReread.Payload.Claims.Where(c => c.Type == "content_hash_algorithm").Single().Value; // Assuming that it always has data var encryptedSecretBase64 = jwtReread.Payload.Claims.Where(c => c.Type == "encrypted_secret_base64").Single().Value; // Assuming that it always has data var encryptedSaltBase64 = jwtReread.Payload.Claims.Where(c => c.Type == "encrypted_salt_base64").Single().Value; // Assuming that it always has data Console.WriteLine($"encryptedKeyBase64={encryptedSecretBase64}"); // Note: The private key from set2 should only be held by opposing party, and never exchanged, as with all private keys var secret = jwtService.Decrypt(encryptedSecretBase64, rsaPrivateKeySet2Contents); // Receivers private key var salt = jwtService.Decrypt(encryptedSaltBase64, rsaPrivateKeySet2Contents); // Receivers private key Console.WriteLine($"secret={secret}"); Console.WriteLine($"salt={salt}"); Console.WriteLine($"secret.Length={secret.Length}"); var decryptedMessage = SymmetricCryptoService.Decrypt(receivedContent, Encoding.UTF8.GetBytes(secret), Encoding.UTF8.GetBytes(salt)); if (decryptedMessage != null && decryptedMessage.Length > 100) { Console.WriteLine($"decryptedMessage={decryptedMessage.Substring(0,100)}"); } else { Console.WriteLine($"decryptedMessage (chunked)={decryptedMessage}"); } Console.WriteLine("decryptedMessage.length=" + decryptedMessage.Length); Console.WriteLine($"contentHashBase64={contentHashBase64}"); //string hexContentHash = BitConverter.ToString(Convert.FromBase64String(contentHashBase64)).Replace("-", ""); //Console.WriteLine($"contentHashHex={hexContentHash}"); // Validate content hash var hashAlgorithm = HashAlgorithmEnum.Parse <HashAlgorithmEnum>(contentHashAlgorithm); if (!jwtService.ValidateBase64Hash(decryptedMessage, contentHashBase64, hashAlgorithm)) { //if(!jwtService.ValidateHexHash(decryptedContent, hexContentHash, hashAlgorithm)) { Console.Error.WriteLine("The content hash has been corrupted, do not continue to use these data!"); SendErrorReply("The content hash has been corrupted, do not continue to use these data!"); } else { Console.WriteLine("JWT was valid and hash was intact!"); SendOKReply("JWT was valid and hash was intact!"); } }