mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-02-09 05:24:55 +00:00
- Updated target frameworks to net48;net8.0;net10.0 only - Removed netstandard2.0 and net481 package conditions - Updated conditional compilation to use NETFRAMEWORK only - Updated package description and README Co-authored-by: adamhathcock <527620+adamhathcock@users.noreply.github.com>
76 lines
2.3 KiB
C#
76 lines
2.3 KiB
C#
using System;
|
|
using System.Buffers.Binary;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
|
|
namespace SharpCompress.Common.Zip;
|
|
|
|
internal class WinzipAesEncryptionData
|
|
{
|
|
private const int RFC2898_ITERATIONS = 1000;
|
|
|
|
private readonly WinzipAesKeySize _keySize;
|
|
|
|
internal WinzipAesEncryptionData(
|
|
WinzipAesKeySize keySize,
|
|
byte[] salt,
|
|
byte[] passwordVerifyValue,
|
|
string password
|
|
)
|
|
{
|
|
_keySize = keySize;
|
|
|
|
#if NETFRAMEWORK
|
|
var rfc2898 = new Rfc2898DeriveBytes(password, salt, RFC2898_ITERATIONS);
|
|
KeyBytes = rfc2898.GetBytes(KeySizeInBytes);
|
|
IvBytes = rfc2898.GetBytes(KeySizeInBytes);
|
|
var generatedVerifyValue = rfc2898.GetBytes(2);
|
|
#elif NET10_0_OR_GREATER
|
|
var derivedKeySize = (KeySizeInBytes * 2) + 2;
|
|
var passwordBytes = Encoding.UTF8.GetBytes(password);
|
|
var derivedKey = Rfc2898DeriveBytes.Pbkdf2(
|
|
passwordBytes,
|
|
salt,
|
|
RFC2898_ITERATIONS,
|
|
HashAlgorithmName.SHA1,
|
|
derivedKeySize
|
|
);
|
|
KeyBytes = derivedKey.AsSpan(0, KeySizeInBytes).ToArray();
|
|
IvBytes = derivedKey.AsSpan(KeySizeInBytes, KeySizeInBytes).ToArray();
|
|
var generatedVerifyValue = derivedKey.AsSpan((KeySizeInBytes * 2), 2).ToArray();
|
|
#else
|
|
var rfc2898 = new Rfc2898DeriveBytes(
|
|
password,
|
|
salt,
|
|
RFC2898_ITERATIONS,
|
|
HashAlgorithmName.SHA1
|
|
);
|
|
KeyBytes = rfc2898.GetBytes(KeySizeInBytes);
|
|
IvBytes = rfc2898.GetBytes(KeySizeInBytes);
|
|
var generatedVerifyValue = rfc2898.GetBytes(2);
|
|
#endif
|
|
|
|
var verify = BinaryPrimitives.ReadInt16LittleEndian(passwordVerifyValue);
|
|
var generated = BinaryPrimitives.ReadInt16LittleEndian(generatedVerifyValue);
|
|
if (verify != generated)
|
|
{
|
|
throw new InvalidFormatException("bad password");
|
|
}
|
|
}
|
|
|
|
internal byte[] IvBytes { get; set; }
|
|
|
|
internal byte[] KeyBytes { get; set; }
|
|
|
|
private int KeySizeInBytes => KeyLengthInBytes(_keySize);
|
|
|
|
internal static int KeyLengthInBytes(WinzipAesKeySize keySize) =>
|
|
keySize switch
|
|
{
|
|
WinzipAesKeySize.KeySize128 => 16,
|
|
WinzipAesKeySize.KeySize192 => 24,
|
|
WinzipAesKeySize.KeySize256 => 32,
|
|
_ => throw new InvalidOperationException(),
|
|
};
|
|
}
|