Exemple #1
0
    public unsafe void SignHash()
    {
        using (var provider = NCryptOpenStorageProvider(KeyStorageProviders.MS_KEY_STORAGE_PROVIDER))
        {
            using (var keyPair = NCryptCreatePersistedKey(provider, BCrypt.AlgorithmIdentifiers.BCRYPT_RSA_ALGORITHM))
            {
                int keySize = GetMinimumKeySize(keyPair);
                NCryptSetProperty(keyPair, KeyStoragePropertyIdentifiers.NCRYPT_LENGTH_PROPERTY, keySize);
                NCryptFinalizeKey(keyPair).ThrowOnError();
                byte[] hashData = SHA1.Create().ComputeHash(new byte[] { 0x1 });
                var    flags    = NCryptSignHashFlags.BCRYPT_PAD_PKCS1;
                fixed(char *pAlgorithm = BCrypt.AlgorithmIdentifiers.BCRYPT_SHA1_ALGORITHM.ToCharArrayWithNullTerminator())
                {
                    var paddingInfo = new BCrypt.BCRYPT_PKCS1_PADDING_INFO()
                    {
                        pszAlgId = pAlgorithm,
                    };

                    byte[] signature = NCryptSignHash(keyPair, &paddingInfo, hashData, flags).ToArray();
                    bool   valid     = NCryptVerifySignature(keyPair, &paddingInfo, hashData, signature, flags);

                    Assert.True(valid);
                    signature[0] = unchecked ((byte)(signature[0] + 1));
                    valid        = NCryptVerifySignature(keyPair, &paddingInfo, hashData, signature, flags);
                    Assert.False(valid);
                }
            }
        }
    }
        /// <summary>
        /// Performs a signing or verification operation.
        /// </summary>
        /// <param name="action">The delegate that will actually perform the cryptographic operation.</param>
        /// <remarks>
        /// This method should not throw an error when verifying a signature and
        /// the signature is invalid. Rather, the delegate should retain the result of
        /// verification and the caller of this method should share that closure and
        /// return the result.
        /// </remarks>
        protected unsafe void SignOrVerify(SignOrVerifyAction action)
        {
            Requires.NotNull(action, nameof(action));

            if (this.SignaturePadding.Value == AsymmetricSignaturePadding.None)
            {
                action(null, NCryptSignHashFlags.None);
            }
            else
            {
                char[] hashAlgorithmName = HashAlgorithmProviderFactory.GetHashAlgorithmName(this.SignatureHash.Value).ToCharArrayWithNullTerminator();
                fixed(char *hashAlgorithmNamePointer = &hashAlgorithmName[0])
                {
                    switch (this.SignaturePadding.Value)
                    {
                    case AsymmetricSignaturePadding.Pkcs1:
                        var pkcs1PaddingInfo = new BCrypt.BCRYPT_PKCS1_PADDING_INFO
                        {
                            pszAlgId = hashAlgorithmNamePointer,
                        };
                        action(&pkcs1PaddingInfo, NCryptSignHashFlags.BCRYPT_PAD_PKCS1);
                        break;

                    case AsymmetricSignaturePadding.Pss:
                        var pssPaddingInfo = new BCrypt.BCRYPT_PSS_PADDING_INFO
                        {
                            pszAlgId = hashAlgorithmNamePointer,
                            cbSalt   = hashAlgorithmName.Length,
                        };
                        action(&pssPaddingInfo, NCryptSignHashFlags.BCRYPT_PAD_PSS);
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                }
            }
        }