public string Decrypt(string encryptedBase64, string password) { PayloadComponents components = this.unpackEncryptedBase64Data(encryptedBase64); if (!this.hmacIsValid(components, password)) { return(""); } byte[] key = this.generateKey(components.salt, password); byte[] plaintextBytes = new byte[0]; switch (this.aesMode) { case AesMode.CTR: // Yes, we are "encrypting" here. CTR uses the same code in both directions. plaintextBytes = this.encryptAesCtrLittleEndianNoPadding(components.ciphertext, key, components.iv); break; case AesMode.CBC: plaintextBytes = this.decryptAesCbcPkcs7(components.ciphertext, key, components.iv); break; } return(Encoding.UTF8.GetString(plaintextBytes)); }
protected byte[] assembleHeader(PayloadComponents components) { List <byte> headerBytes = new List <byte>(); headerBytes.AddRange(components.schema); headerBytes.AddRange(components.options); headerBytes.AddRange(components.salt); headerBytes.AddRange(components.hmacSalt); headerBytes.AddRange(components.iv); return(headerBytes.ToArray()); }
private bool hmacIsValid(PayloadComponents components, string password) { byte[] generatedHmac = this.generateHmac(components, password); if (generatedHmac.Length != components.hmac.Length) { return(false); } for (int i = 0; i < components.hmac.Length; i++) { if (generatedHmac[i] != components.hmac[i]) { return(false); } } return(true); }
protected byte[] generateHmac(PayloadComponents components, string password) { List <byte> hmacMessage = new List <byte>(); if (this.hmac_includesHeader) { hmacMessage.AddRange(this.assembleHeader(components)); } hmacMessage.AddRange(components.ciphertext); byte[] key = this.generateKey(components.hmacSalt, password); HMAC hmacAlgo = null; switch (this.hmac_algorithm) { case HmacAlgorithm.SHA1: hmacAlgo = new HMACSHA1(key); break; case HmacAlgorithm.SHA256: hmacAlgo = new HMACSHA256(key); break; } List <byte> hmac = new List <byte>(); hmac.AddRange(hmacAlgo.ComputeHash(hmacMessage.ToArray())); if (this.hmac_includesPadding) { for (int i = hmac.Count; i < Cryptor.hmac_length; i++) { hmac.Add(0x00); } } return(hmac.ToArray()); }
public string Encrypt(string plaintext, string password, Schema schemaVersion) { this.configureSettings(schemaVersion); byte[] plaintextBytes = TextEncoding.GetBytes(plaintext); PayloadComponents components = new PayloadComponents(); components.schema = new byte[] { (byte)schemaVersion }; components.options = new byte[] { (byte)this.options }; components.salt = this.generateRandomBytes(Cryptor.saltLength); components.hmacSalt = this.generateRandomBytes(Cryptor.saltLength); components.iv = this.generateRandomBytes(Cryptor.ivLength); byte[] key = this.generateKey(components.salt, password); switch (this.aesMode) { case AesMode.CTR: components.ciphertext = this.encryptAesCtrLittleEndianNoPadding(plaintextBytes, key, components.iv); break; case AesMode.CBC: components.ciphertext = this.encryptAesCbcPkcs7(plaintextBytes, key, components.iv); break; } components.hmac = this.generateHmac(components, password); List <byte> binaryBytes = new List <byte>(); binaryBytes.AddRange(this.assembleHeader(components)); binaryBytes.AddRange(components.ciphertext); binaryBytes.AddRange(components.hmac); return(Convert.ToBase64String(binaryBytes.ToArray())); }