<PackageReference Include="BouncyCastle.Cryptography" Version="2.5.1" />

Pkcs12ParametersGenerator

using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; using System; namespace Org.BouncyCastle.Crypto.Generators { public class Pkcs12ParametersGenerator : PbeParametersGenerator { public const int KeyMaterial = 1; public const int IVMaterial = 2; public const int MacMaterial = 3; private readonly IDigest digest; private readonly int u; private readonly int v; public Pkcs12ParametersGenerator(IDigest digest) { this.digest = digest; u = digest.GetDigestSize(); v = digest.GetByteLength(); } private void Adjust(byte[] a, int aOff, byte[] b) { uint num = (uint)(b[b.Length - 1] + a[aOff + b.Length - 1] + 1); a[aOff + b.Length - 1] = (byte)num; num >>= 8; for (int num2 = b.Length - 2; num2 >= 0; num2--) { num = (uint)((int)num + (b[num2] + a[aOff + num2])); a[aOff + num2] = (byte)num; num >>= 8; } } private byte[] GenerateDerivedKey(byte idByte, int n) { byte[] array = new byte[n]; GenerateDerivedKey(idByte, array); return array; } private void GenerateDerivedKey(byte idByte, Span<byte> dKey) { byte[] array = new byte[v]; Arrays.Fill(array, idByte); byte[] array2 = Array.Empty<byte>(); if (!Arrays.IsNullOrEmpty(mSalt)) { array2 = new byte[v * ((mSalt.Length + v - 1) / v)]; RepeatFill(mSalt, array2); } byte[] array3 = Array.Empty<byte>(); if (!Arrays.IsNullOrEmpty(mPassword)) { array3 = new byte[v * ((mPassword.Length + v - 1) / v)]; RepeatFill(mPassword, array3); } byte[] array4 = Arrays.Concatenate(array2, array3); byte[] array5 = new byte[u]; byte[] array6 = new byte[v]; int num = (dKey.Length + u - 1) / u; for (int i = 1; i <= num; i++) { digest.BlockUpdate(array, 0, array.Length); digest.BlockUpdate(array4, 0, array4.Length); digest.DoFinal(array5, 0); for (int j = 1; j != mIterationCount; j++) { digest.BlockUpdate(array5, 0, array5.Length); digest.DoFinal(array5, 0); } RepeatFill(array5, array6); for (int k = 0; k < array4.Length; k += v) { Adjust(array4, k, array6); } if (i == num) dKey.Slice((i - 1) * u).CopyFrom(array5); else array5.CopyTo(dKey.Slice((i - 1) * u)); } } public override ICipherParameters GenerateDerivedParameters(string algorithm, int keySize) { keySize /= 8; byte[] keyBytes = GenerateDerivedKey(1, keySize); return ParameterUtilities.CreateKeyParameter(algorithm, keyBytes, 0, keySize); } public override ICipherParameters GenerateDerivedParameters(string algorithm, int keySize, int ivSize) { keySize /= 8; ivSize /= 8; byte[] keyBytes = GenerateDerivedKey(1, keySize); return ParametersWithIV.Create(ParameterUtilities.CreateKeyParameter(algorithm, keyBytes, 0, keySize), ivSize, this, delegate(Span<byte> bytes, Pkcs12ParametersGenerator self) { self.GenerateDerivedKey(2, bytes); }); } public override ICipherParameters GenerateDerivedMacParameters(int keySize) { keySize /= 8; return KeyParameter.Create(keySize, this, delegate(Span<byte> bytes, Pkcs12ParametersGenerator self) { self.GenerateDerivedKey(3, bytes); }); } private static void RepeatFill(byte[] x, byte[] z) { int num = x.Length; int num2 = z.Length; int i; for (i = 0; i < num2 - num; i += num) { Array.Copy(x, 0, z, i, num); } Array.Copy(x, 0, z, i, num2 - i); } } }