/// <inheritdoc /> public override string Crypt(byte[] password, string salt) { Check.Null("password", password); Check.Null("salt", salt); Match match = _regex.Match(salt); if (!match.Success) { throw Exceptions.Argument("salt", "Invalid salt."); } byte[] roundsBytes = null, saltBytes = null, crypt = null, input = null; try { string roundsString = match.Groups["rounds"].Value; roundsBytes = Base64Encoding.UnixMD5.GetBytes(roundsString); int roundsValue = (int)BitPacking.UInt24FromLEBytes(roundsBytes, 0); string saltString = match.Groups["salt"].Value; saltBytes = Base64Encoding.UnixMD5.GetBytes(saltString); int saltValue = (int)BitPacking.UInt24FromLEBytes(saltBytes, 0); input = new byte[8]; int length = ByteArray.NullTerminatedLength(password, password.Length); for (int m = 0; m < length; m += 8) { if (m != 0) { using (DesCipher cipher = DesCipher.Create(input)) { cipher.Encipher(input, 0, input, 0); } } for (int n = 0; n < 8 && n < length - m; n++) { // DES Crypt ignores the high bit of every byte. input[n] ^= (byte)(password[m + n] << 1); } } using (DesCipher cipher = DesCipher.Create(input)) { crypt = new byte[8]; cipher.Crypt(crypt, 0, roundsValue, saltValue); } return("_" + roundsString + saltString + Base64Encoding.UnixCrypt.GetString(crypt)); } finally { Security.Clear(roundsBytes); Security.Clear(saltBytes); Security.Clear(crypt); Security.Clear(input); } }
/// <inheritdoc /> public override string Crypt(byte[] password, string salt) { Check.Null("password", password); Check.Null("salt", salt); Match match = _regex.Match(salt); if (!match.Success) { throw Exceptions.Argument("salt", "Invalid salt."); } byte[] crypt = null, input = null; try { string saltString = FilterSalt(match.Groups["salt"].Value); input = new byte[8]; int length = ByteArray.NullTerminatedLength(password, input.Length); Array.Copy(password, input, Math.Min(length, input.Length)); // DES Crypt ignores the high bit of every byte. for (int n = 0; n < 8; n++) { input[n] <<= 1; } using (DesCipher cipher = DesCipher.Create(input)) { int saltValue = Base64Encoding.UnixCrypt.GetValue(saltString[0]) << 0 | Base64Encoding.UnixCrypt.GetValue(saltString[1]) << 6; crypt = new byte[8]; cipher.Crypt(crypt, 0, 25, saltValue); } return(saltString + Base64Encoding.UnixCrypt.GetString(crypt)); } finally { Security.Clear(crypt); Security.Clear(input); } }