Esempio n. 1
0
        private static AsnWriter RewriteEncryptedPkcs8PrivateKey(
            AsymmetricAlgorithm key,
            ReadOnlySpan <char> password,
            PbeParameters pbeParameters)
        {
            Debug.Assert(pbeParameters != null);

            byte[] rented      = CryptoPool.Rent(key.KeySize);
            int    rentWritten = 0;

            try
            {
                while (!key.TryExportEncryptedPkcs8PrivateKey(
                           password,
                           s_platformParameters,
                           rented,
                           out rentWritten))
                {
                    int    size    = rented.Length;
                    byte[] current = rented;
                    rented = CryptoPool.Rent(checked (size * 2));
                    CryptoPool.Return(current, rentWritten);
                }

                return(KeyFormatHelper.ReencryptPkcs8(
                           password,
                           rented.AsMemory(0, rentWritten),
                           password,
                           pbeParameters));
            }
            finally
            {
                CryptoPool.Return(rented, rentWritten);
            }
        }
Esempio n. 2
0
        private static AsnWriter RewriteEncryptedPkcs8PrivateKey(
            AsymmetricAlgorithm key,
            ReadOnlySpan <byte> passwordBytes,
            PbeParameters pbeParameters)
        {
            Debug.Assert(pbeParameters != null);

            // For RSA:
            //  * 512-bit key needs ~400 bytes
            //  * 16384-bit key needs ~10k bytes.
            //  * KeySize (bits) should avoid re-rent.
            //
            // For DSA:
            //  * 512-bit key needs ~300 bytes.
            //  * 1024-bit key needs ~400 bytes.
            //  * 2048-bit key needs ~700 bytes.
            //  * KeySize (bits) should avoid re-rent.
            //
            // For ECC:
            //  * secp256r1 needs ~200 bytes (named) or ~450 (explicit)
            //  * secp384r1 needs ~250 bytes (named) or ~600 (explicit)
            //  * secp521r1 needs ~300 bytes (named) or ~730 (explicit)
            //  * KeySize (bits) should avoid re-rent for named, and probably
            //    gets one re-rent for explicit.
            byte[] rented = ArrayPool <byte> .Shared.Rent(key.KeySize);

            int rentWritten = 0;

            // If we use 6 bits from each byte, that's 22 * 6 = 132
            Span <char> randomString = stackalloc char[22];

            try
            {
                FillRandomAsciiString(randomString);

                while (!key.TryExportEncryptedPkcs8PrivateKey(
                           randomString,
                           s_platformParameters,
                           rented,
                           out rentWritten))
                {
                    int size = rented.Length;
                    ArrayPool <byte> .Shared.Return(rented);

                    rented = ArrayPool <byte> .Shared.Rent(checked (size * 2));
                }

                return(KeyFormatHelper.ReencryptPkcs8(
                           randomString,
                           rented.AsMemory(0, rentWritten),
                           passwordBytes,
                           pbeParameters));
            }
            finally
            {
                randomString.Clear();
                CryptographicOperations.ZeroMemory(rented.AsSpan(0, rentWritten));
                ArrayPool <byte> .Shared.Return(rented);
            }
        }