private void DecryptTokenRecursive(JToken jToken, byte[] privateKey) { if (jToken.HasValues) { foreach (var child in jToken) { DecryptTokenRecursive(child, privateKey); } } else if (IsEncryptable(jToken)) { try { var valueStirng = jToken.Value <string>(); if (BoxedMessage.IsBoxedMessage(valueStirng) && BoxedMessage.TryCreate(valueStirng, out BoxedMessage boxedMessage)) { var decryptedValue = _boxedMessageCrypto.Decrypt(boxedMessage, privateKey); ((JProperty)jToken.Parent).Value = decryptedValue; } ; } catch { // TODO: make error behavior configurable throw; } } }
private void EncryptTokenRecursive(JToken jToken, byte[] publicKey) { if (jToken.HasValues) { foreach (var child in jToken) { EncryptTokenRecursive(child, publicKey); } } else if (IsEncryptable(jToken)) { try { var valueStirng = jToken.Value <string>(); if (!BoxedMessage.IsBoxedMessage(valueStirng)) { var encryptedValue = _boxedMessageCrypto.Encrypt(valueStirng, publicKey).ToString(); ((JProperty)jToken.Parent).Value = encryptedValue; } ; } catch { // TODO: make error behavior configurable throw; } } }
/* * from: https://shopify.github.io/ejson/ejson.5.html * * SECRET SCHEMA * When a value is encrypted, it will be replaced by a relatively long string of the form "EJ[V:P:N:M]". The fields are: * * V (decimal-as-string int) * Schema Version, hard-coded to "1" for now * * P (base64-encoded 32-byte array) * Public key of an ephemeral keypair used to encrypt this key * * N (base64-encoded 24-byte array) * Nonce used to encrypt this key * * M (base64-encoded variable-length array) * Raw ciphertext */ public static bool TryCreate(string secret, out BoxedMessage result) { try { result = Create(secret); return(true); } catch { result = null; return(false); } }
public string Decrypt(BoxedMessage boxedMessage, byte[] privateKey) { if (boxedMessage.SchemaVersion == SchemaVersion) { var nonce = Convert.FromBase64String(boxedMessage.NonceBase64); var ephemeralPublicKey = Convert.FromBase64String(boxedMessage.PublicKeyBase64); var cipherText = Convert.FromBase64String(boxedMessage.EncryptedMessageBase64); var decryptedBytes = _publicKeyBox.Open(cipherText, nonce, privateKey, ephemeralPublicKey); var decryptedString = _encoding.GetString(decryptedBytes); return(decryptedString); } else { throw new NotSupportedException(); } }
public BoxedMessage Encrypt(string nessage, byte[] publicKey) { var messageBytes = _encoding.GetBytes(nessage); var nonce = _publicKeyBox.GenerateNonce(); var ephemeralKeyPair = _publicKeyBox.GenerateKeyPair(); var encryptedBytes = _publicKeyBox.Create(messageBytes, nonce, ephemeralKeyPair.SecretKey, publicKey); var boxedMessage = new BoxedMessage { EncryptedMessageBase64 = Convert.ToBase64String(encryptedBytes), PublicKeyBase64 = Convert.ToBase64String(ephemeralKeyPair.PublicKey), NonceBase64 = Convert.ToBase64String(nonce), SchemaVersion = SchemaVersion, }; return(boxedMessage); }
public static BoxedMessage Create(string boxedMessageAsString) { var match = _regex.Match(boxedMessageAsString); if (!match.Success) { throw new ArgumentException("Cannot parse secret. Must be inthe form 'EJ[V: P:N: M]'.", nameof(boxedMessageAsString)); } var result = new BoxedMessage(); result.SchemaVersion = match.Groups["V"].Value; result.PublicKeyBase64 = match.Groups["P"].Value; result.NonceBase64 = match.Groups["N"].Value; result.EncryptedMessageBase64 = match.Groups["M"].Value; return(result); }
public static string Decrypt(this IBoxedMessageCrypto boxedMessageCrypto, BoxedMessage boxedMessage, string privateKey) { var privateKeyBytes = HexConverter.HexToBinary(privateKey); return(boxedMessageCrypto.Decrypt(boxedMessage, privateKeyBytes)); }
public static string Decrypt(this IBoxedMessageCrypto boxedMessageCrypto, string boxedMessageAsString, byte[] privateKey) { var boxedMessage = BoxedMessage.Create(boxedMessageAsString); return(boxedMessageCrypto.Decrypt(boxedMessage, privateKey)); }