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); }
public static String ToJWTBase64(dynamic data, ILogger logger, ISecurityVault securityVault, String issuer, String secret, String salt, String senderPrivateKeyName, String receiverPublicKeyName) { IJWTService jwtService = new RSAJWTService(); var longSecretData = JsonConvert.SerializeObject(data); var symCryptoKey = SymmetricCryptoService.CreateSymmetricKey(securityVault.GetSecret(secret), securityVault.GetSecret(salt)); var encryptedData = SymmetricCryptoService.Encrypt(longSecretData, symCryptoKey.Key, symCryptoKey.IV); logger.LogInformation($"encryptedData:{encryptedData}"); //var decryptedData = SymmetricCryptoService.Decrypt(encryptedData, symCryptoKey.Key, symCryptoKey.IV); //logger.LogInformation($"decryptedData:{decryptedData}"); var rsaPrivateKeySet1Contents = securityVault.GetSecret(senderPrivateKeyName); var rsaPublicKeySet2Contents = securityVault.GetSecret(receiverPublicKeyName); var validationParameters = getValidationParameters(issuer); var payload = new JwtPayload { { "iss", issuer }, { "encrypted_key_bas64", jwtService.Encrypt(secret, rsaPublicKeySet2Contents) }, // Receivers public key { "encrypted_iv_bas64", jwtService.Encrypt(salt, rsaPublicKeySet2Contents) }, // Receivers public key { "sym_encrypted_data", SymmetricCryptoService.Encrypt(longSecretData, symCryptoKey.Key, symCryptoKey.IV) }, // These data can be large { "exp", (Int32)(DateTime.UtcNow.AddHours(1).Subtract(new DateTime(1970, 1, 1))).TotalSeconds }, { "iat", (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds } }; // Creating signed JWT var jwt = jwtService.GenerateJWTFromRSA(payload, rsaPrivateKeySet1Contents, "RS256"); // Senders private key var serializedJWT = new JwtSecurityTokenHandler().WriteToken(jwt); logger.LogInformation($"serializedJWT:{serializedJWT}"); return(serializedJWT); }
private static void SimulateReceiverWithBadKey() { var simpleMessage = GetRequest(); IJWTService jwtService = new RSAJWTService(); // Trying with a bad key var jwtRereadBad = jwtService.ReadJWTRSA(simpleMessage.AuthorizationHeader, RSAPublicKeySet1BadContents, "RS256", BuildValidationParameters()); }
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!"); } }
public SimpleCrypto(string secret, string salt) { this.secret = secret; this.salt = salt; JWTService = new RSAJWTService(); Algorithm = AlgorithmEnum.RSA256; Issuer = "opusmagus.com"; ExpirationDate = new DateTime(1970, 1, 1); symCryptoKey = SymmetricCryptoService.CreateSymmetricKey(secret, salt); }
private static void SimulateSender() { IJWTService jwtService = new RSAJWTService(); var longSecretData = File.ReadAllText($@"{LocalFileStorePath}\data\large-text1.txt"); var secret = "my-awesome-pw123"; // Should be exactly 16 bytes var salt = "my-tasty-salt123"; // Should be exactly 16 bytes var symCryptoKey = SymmetricCryptoService.CreateSymmetricKey(secret, salt); if (longSecretData != null && longSecretData.Length > 100) { Console.WriteLine("longSecretData=" + longSecretData.Substring(0, 100)); } else { Console.WriteLine("longSecretData=" + longSecretData); } Console.WriteLine("longSecretData.length=" + longSecretData.Length); // This key is only known by one party "A" var rsaPrivateKeySet1Contents = File.ReadAllText($@"{LocalFileStorePath}\keys\rsa-prv-key-set1.key"); var contentHashBase64 = jwtService.GenerateBase64Hash(longSecretData, HashAlgorithmEnum.SHA512); var payload = new JwtPayload { { "iss", "commentor.dk" }, { "encrypted_secret_base64", jwtService.Encrypt(secret, RSAPublicKeySet2Contents) }, // Receivers public key { "encrypted_salt_base64", jwtService.Encrypt(salt, RSAPublicKeySet2Contents) }, // Receivers public key { "content_hash_base64", contentHashBase64 }, { "content_hash_algorithm", HashAlgorithmEnum.SHA512.ToString() }, { "exp", (Int32)(DateTime.UtcNow.AddHours(1).Subtract(new DateTime(1970, 1, 1))).TotalSeconds }, { "iat", (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds } }; // Creating signed JWT var jwt = jwtService.GenerateJWTFromRSA(payload, rsaPrivateKeySet1Contents, "RS256"); // Senders private key var serializedJWT = new JwtSecurityTokenHandler().WriteToken(jwt); Console.WriteLine($"serializedJWT:{serializedJWT}"); var rijndaelEncryptedDataBase64 = SymmetricCryptoService.Encrypt(longSecretData, Encoding.UTF8.GetBytes(secret), Encoding.UTF8.GetBytes(salt)); Console.WriteLine($"rijndaelEncryptedDataBase64HashBase64:{jwtService.GenerateBase64Hash(rijndaelEncryptedDataBase64, HashAlgorithmEnum.SHA512)}"); Console.WriteLine($"contentHashBase64:{contentHashBase64}"); var simpleMessage = new SimpleMessage { AuthorizationHeader = serializedJWT, BodyContents = rijndaelEncryptedDataBase64 }; SendRequest(simpleMessage); }