<!--
meta-author: David Ireland, DI Management Services Pty Limited, Australia, www.di-mgt.com.au
meta-content-style-type: text/css
meta-content-type: text/html; charset=UTF-8
meta-copyright: Copyright (C) 2004-25 DI Management Services Pty Limited, ABN 78 083 210 584 All Rights Reserved
meta-date: 2024-01-01T11:52:09Z
meta-description: CryptoSys PKI Pro for Visual Basic and C/C++/C#
meta-keywords: cryptography, PKI, Public Key Infrastructure,
		cryptographic security services for electronic messaging applications, 
		computer security, telecommunication security, cryptographic modules,
		application programming interface, API, DLL, developer tool,
		Public Key Cryptography Standards, PKCS, RSA, RSAES-PKCS-v1_5, RSASSA-PKCS-v1_5, RSAES-OAEP, RSASSA-PSS, RSA-KEM,
		public key encryption, digital signature, RSA algorithm,
		X.509 certificate, X.509 certificate revocation list, CRL, Online Certification Status Protocol, OCSP,
		cryptographic message syntax, CMS, PKCS#1, PKCS#5, PKCS#7, PKCS#8, PKCS#10, PKCS#12, PFX,
		signed-data, enveloped-data, compressed-data, zlib compression,
		elliptic curve cryptography, ECDSA, Ed25519, Ed448,
		Diffie-Hellman key exchange, ECDH, X25519, X448, ANSI-X9.63-KDF, HKDF,
		JSON Web Signature (JWS), JSON Web Key (JWK), GUID, UUID,
		S/MIME, Secure/Multipurpose Internet Mail Extensions, XML-DSIG, AUTACK, PAYMUL, EDIFACT, triple DES,
		DES, AES, AES-128, AES-192, AES-256, AES-GCM, AEAD_AES_128_GCM, AEAD_AES_256_GCM, ChaCha20Poly1305, 
		authenticated encryption, AEAD, ASN.1,
		secure random number generator, RNG, NIST SP800-90A, Intel(R) DRNG,
		cryptographic hash function, SHA-1, SHA-2, SHA-3, Keccak, SHAKE128, SHAKE256, KMAC,
		Hybrid Public Key Encryption, HPKE, 
		Microsoft Visual Basic, VB6, VBA, `VB.NET`,
		C programming language, C (Computer Program Language), C++, C#, CSharp, .NET, DotNet, Python
meta-viewport: width=device-width, initial-scale=1
title: PKIv23.0.1 | CryptoSys PKI Pro Toolkit Manual
-->

<a id="topofpage"></a>CryptoSys PKI Pro Manual
==============================================

[Function List](#vb6funcsummary)   
[X-refs](#xrefdotnet)   
[Method List](#dotnetsummary)   
[Error Codes](#errorcodes)   
[References](#References)   
[Index](#index)

Contents
--------

* [Introduction to CryptoSys PKI Pro](#Introduction)
* [Getting Started](#gettingstarted)
* [New in this version](#newinthis)
* [Changes in earlier versions](#changesearlier)
* [Conventions in this document](#Conventions)
* [Copyright Notice](#Copyright)
* [Theory](#Theory)
* [Supported Algorithms](#SupportedAlgorithms)

    + [CMS Content Types](#supportedcmstypes)
        + [Unsupported algorithms](#unsupportedalgorithms)
        + [Key Storage Format (RSA)](#Keystorage)
        + [Key Storage Format (ECC)](#Keystorage-ecc)
* [A caution about insecure default algorithms](#cautionwithdefaults)
* [Installation](#installation)

    + [Win64 (X64) Platform](#win64platform)
        + [Detecting Win32 or X64 platform](#detectingplatform)
* [Visual Basic or Visual Basic: VB6 vs `VB.NET`](#vb6vsvbdotnet)
* [General Programming Issues](#generalprogramming)

    + [Return Values](#ReturnValues)
        + ['Hello world' programs](#helloworld)
        + [Converting strings to bytes and vice versa](#stringstobytes)
        + [Converting VB6 to `VB.NET`](#vb6tovbnet)
* [Using with Classic Visual Basic VB6 and VBA](#UsingWithVB)

    + [Core VBA/VB6 functions vs better wrapper functions](#corevbavswrappers)
        + [Pre-dimensioning for VB6](#predimensioning)
        + [Find length of byte array](#findlengthbytearray)
        + [Zero-length byte arrays in VB6/VBA](#zerolengthbytearrays)
        + [Passing a reference to an empty byte array in VB6/VBA](#passemptybytearray)
        + [Other Issues For VB6/VBA Users](#otherissuesvb6)
        + [Notes on VBA wrapper functions](#notesonvbawrapperfunctions)
* [Using with ANSI C](#UsingWithC)

    + [Type Conversions](#typeconversions)
        + [Compiling with C](#compilingwithc)
        + [Using With Borland C++](#borlandc)
        + [Using With MinGW gcc](#mingw)
        + [Cautions for C/C++ Users](#cautionsforcusers)
        + [C/C++ users must add one to this value...](#cusersaddone)
        + [Examples of C code](#examplesccode)
* [Using with C++ (STL)](#UsingWithCpp)
* [Using with .NET: C# and `VB.NET`](#UsingWithDotNet)

    + [Combining bitwise options](#bitwiseoptions)
* [Using with Python](#UsingWithPython)
* [UTF-8 and Latin-1](#utf8andlatin1)
* [Filenames with 'International' characters](#filenamesinternational)
* [Security Issues](#securityissues)
* [Key Security](#keysecurity)
* [Internal key strings](#internalkeys)
* [Security options for encrypted private keys](#encryptedkeyoptions)
* [Elliptic Curve Cryptography (ECC)](#eccrypto)

    + [Hex format for NIST/SEC EC keys](#ecchexformat)
        + [Can you read a key in compressed representation?](#compressedkey)
* [Safe curves for elliptic cryptography](#eccsafecurves)
* [Technical Details](#technicaldetails)
* [Self-Tests](#selftests)

    + [Power-up Self-Tests](#powerupselftests)
            - [Cryptographic algorithm test:](#cryptoalgtest)
                - [RNG health test:](#rnghealthtest)
                - [Software integrity test:](#softwareintegritytest)
        + [Conditional Tests](#conditionaltests)
            - [Pair-wise consistency test:](#pairwiseconsistencytest)
                - [Continuous random number generator test:](#rngtest)
        + [Action if a self-test fails](#selftestfails)
* [Critical Errors](#criticalerrors)
* [Optional Registry Settings](#registrysettings)
* [Random Number Generator](#rnginfo)

    + [RNG Mechanisms](#rngmechanisms)
        + [Intel(R) DRNG support](#inteldrng)
        + [Techniques to add known security strength to the RNG process](#rngtechniques)
        + [User-supplied entropy (seeds)](#rngentropy)
* [Specifying Distinguished Names](#distnames)

    + [Default encoding](#dndefaultencoding)
        + [UTF-8 encoding in distinguished names](#utf8forDN)
        + [Specifying an arbitrary RDN in a distinguished name](#arbitraryrdn)
* [LDAP String Representation of Distinguished Names](#ldapstring)
* [X.509 Extensions Parameter](#x509extensions)

    + [Add an arbitrary X.509 Extension](#arbitraryx509extn)
* [AOC policy for X.509 content](#aocpolicy)
* [ISO 8601 date-time formats](#iso8601datetime)
* [ASN.1 objects: binary DER- and BER-encoded files vs PEM-encoded text files](#asn1objects)
* [Base64 alternative for X.509 certificates](#base64forcert)
* [PEM string alternative for X.509 certificates, RSA and EC keys, etc](#pemstring)
* [Base64 and PEM string alternatives for CMS objects](#cmsbase64pem)
* [Specifying the algorithm, mode and padding for generic block cipher functions](#cipheralgmode)
* [Padding schemes for block ciphers](#paddingschemes)
* [Valid key and block sizes for block cipher algorithms](#blockciphersizes)
* [Specifying the signature algorithm in a SIG_ function](#sigalgorithm)
* [AUTACK messages and ISO/IEC 9796-1 signatures](#autackmsgs)

    + [ISO/IEC 9796-1 Formatting](#iso9796format)
        + [RSA2 Signing](#rsa2sign)
* [CMS Content Types](#cmstypes)

    + [CMS SignedData objects](#signeddata)
            - [Additional security attributes New in v12.4](#additionalsecurityattributes)
        + [CMS EnvelopedData objects](#envelopeddata)
        + [CMS AuthEnvelopedData objects](#authenvelopeddata)
* [Using in MIME-conformant email messages](#usinginmime)
* [Using output in XML documents](#xmldocs)
* [Base64url encoding and JSON Web Signatures (JWS)](#base64url)
* [Raw RSA Techniques](#rawrsa)
* [RSA signature and encryption schemes: RSA-PSS and RSA-OAEP](#rsaschemes)

    + [Parameters for RSA-PSS and RSA-OAEP available in this Toolkit](#parametersrsapssoaep)
* [Elliptic curve Diffie-Hellman (ECDH)](#ecdh)
* [Authenticated Encryption with Associated Data (AEAD)](#authencryptionaad)
* [Hybrid Public Key Encryption (HPKE)](#hybridpke)
* [HASH vs XOF vs MAC vs PRF vs KDF](#prfxof)
* [VB6/C Function Summary](#vb6funcsummary)

    + [ASN.1 analysis functions](#asn1functions)
        + [Block Cipher Functions](#cipherfunctions)
        + [CMS functions](#cmsfunctions)
        + [Conversion functions](#cnvfunctions)
        + [Compression functions](#comprfunctions)
        + [Certificate Revocation List (CRL) functions](#crlfunctions)
        + [Elliptic curve cryptography functions](#eccfunctions)
        + [General functions](#genfunctions)
        + [Message Digest Hash Functions](#hashfunctions)
        + [HMAC Functions](#hmacfunctions)
        + [Hybrid Public Key Encryption (HPKE) functions](#hpkefunctions)
        + [Key Derivation Functions](#kdffunctions)
        + [OCSP Functions](#ocspfunctions)
        + [Padding functions](#padfunctions)
        + [Password-based encryption functions](#pbefunctions)
        + [PEM/binary file conversion functions](#pemfunctions)
        + [PFX Functions](#pfxfunctions)
        + [Pseudorandom functions (PRF)](#prffunctions)
        + [Password prompt functions](#promptfunctions)
        + [Random number generator functions](#rngfunctions)
        + [RSA key functions](#rsafunctions)
        + [Raw RSA functions](#rawrsafunctions)
        + [SIG functions](#sigfunctions)
        + [S/MIME functions](#smimefunctions)
        + [Triple DES (TDEA/3DES) Functions](#tdeafunctions)
        + [Wipe functions](#wipefunctions)
        + [X.509 certificate functions](#x509functions)
        + [eXtendable-output functions (XOF)](#xoffunctions)
* [List of Functions](#functionlist)
* [VBA Wrapper Functions](#vbawrapperfunctions)

    + [VBA Wrapper Function List](#vbawrapperfunctionlist)
* [C++ (STL) Functions](#cppfunctions)
* [.NET Classes and Methods](#dotnetclassesandmethods)

    + [Cross-reference between Functions and .NET Methods](#xrefdotnet)
        + [.NET Help File](#dotnethelp)
* [Summary of .NET Classes](#dotnetsummary)

    + [Asn1 Class](#mx_Asn1)
        + [Cipher Class](#mx_Cipher)
        + [Cms Class](#mx_Cms)
        + [Cnv Class](#mx_Cnv)
        + [Compr Class](#mx_Compr)
        + [Ecc Class](#mx_Ecc)
        + [General Class](#mx_General)
        + [Hash Class](#mx_Hash)
        + [Hmac Class](#mx_Hmac)
        + [Hpke Class](#mx_Hpke)
        + [Kdf Class](#mx_Kdf)
        + [Ocsp Class](#mx_Ocsp)
        + [Pbe Class](#mx_Pbe)
        + [Pem Class](#mx_Pem)
        + [Pfx Class](#mx_Pfx)
        + [Prf Class](#mx_Prf)
        + [Pwd Class](#mx_Pwd)
        + [Rng Class](#mx_Rng)
        + [Rsa Class](#mx_Rsa)
        + [Sig Class](#mx_Sig)
        + [Smime Class](#mx_Smime)
        + [Tdea Class](#mx_Tdea)
        + [Wipe Class](#mx_Wipe)
        + [X509 Class](#mx_X509)
        + [Xof Class](#mx_Xof)
* [List of .Net Methods](#methodlist)
* [Enumerations in .NET](#dotnetenumerations)
* [Error Handling and Error Codes](#errorcodes)
* [Acknowledgements](#acks)
* [Primary References](#References)
* [Bibliography](#Bibliography)
* [Index](#index)
* [Revision History](#Revisions)

<a id="Introduction"></a>Introduction to CryptoSys PKI Pro
----------------------------------------------------------

CryptoSysTM PKI Pro is an interface to public key cryptography functions
and associated cryptography utilities for Visual Basic, C/C++ and C# programmers on Windows systems.
It provides strong crypto using established non-patented technology to international standards.

You can create and read secure cryptographic messages encrypted or signed using RSA public key encryption.
The results can be used in XML documents using the XML-DSIG and XML-ENC specifications.

You can create and read enveloped-data (encrypted), signed-data and compressed-data Cryptographic Message Syntax (CMS, PKCS#7) objects,
which you can wrap in S/MIME entities and use in S/MIME email messages. You can verify the digital signature in a signed-data CMS object;
generate and manage RSA public and private keys; carry out "raw" RSA encryption and decryption, 
and create, read and manage X.509 certificate files and CRLs.

You can create signatures using ECDSA with elliptic curves over primes. You can create new keys and read existing
curves in the standard formats.

Other utilities included in the toolkit are the ability to generate message digest hash values using 
SHA-1, SHA-2, SHA-3, RIPEMD-160, MD5, MD2; 
generate HMAC keyed-hash message authentication values, 
wipe files using 7-pass DOD standards, 
generate cryptographically-secure random numbers to the strict NIST SP800-90 standard, 
prompt for a password, and convert to and from base64- and hexadecimal-encoded formats.

Public Key Infrastructure (PKI) is defined in [[PKIX-MAP](#PKIX-MAP)] as

> The set of hardware, software,
> people, policies and procedures needed to create, manage, store,
> distribute, and revoke Public Key Certificates based on public-key cryptography.

The CryptoSys PKI Pro toolkit provides programmers and developers
with most of the useful algorithms you need to create the software for a true PKI.
We have appropriated a well-known three-letter-acronym. 
CryptoSys PKI Pro is a sharp tool.
It's up to you to manage the hardware, people, policies, procedures and the overall software security you require.

You might also find an alternative definition of PKI from the Devil's Infosec Dictionary [[DEVIL](#DEVIL)]
both amusing and relevant.

> A system designed to transfer all of the complexities of strong authentication onto end users.

We have used *S/MIME Version 3 Message Specification* [[SMIME-MSG](#SMIME-MSG)],
and *Cryptographic Message Syntax (CMS)* [[CMS](#CMS)] together with the relevant PKCS documents
as our [primary reference](#References) documents.  
CMS is a stricter subset of PKCS#7 [[PKCS7](#PKCS7)] and is compatible with it.

The CMS (PKCS#7) objects produced by this toolkit should be readable by 
S/MIME-compatible email clients like Thunderbird
if they are wrapped in [MIME-conformant email messages](#usinginmime). 
You need to use your own separate program to create, send and read MIME email messages.
You can create most of the cryptographic elements required in the 
[[XML-DSIG](#XMLDSIG)] and [[XML-ENC](#XMLENC)] specifications to insert into [XML documents](#xmldocs),
but there are no explicit XML processing facilities.
The X.509 certificate tools should be compatible with typical certificates issued by Verisign and Thawte. 
The certificate signing requests (CSRs) it creates are accepted by Verisign's test facility,
provided you include the distinguished name attributes they require. 
As of [v12.0] there is actually a facility to add an MPEG video of you playing with your cat into an X.509 certificate, should you wish.

<a id="gettingstarted"></a>Getting Started
------------------------------------------

To get started, read the section on [Installation](#installation) and 
the section on your programming language:

* [Using with Classic Visual Basic and VBA](#UsingWithVB)
* [Using with C and C++](#UsingWithC)
* [Using with C++ (STL)](#UsingWithCpp)
* [Using with .NET: C# and `VB.NET`](#UsingWithDotNet)
* [Using with Python](#UsingWithPython)

and if you are a Visual Basic user, please read [Visual Basic or Visual Basic: VB6 vs `VB.NET`](#vb6vsvbdotnet).

Then try one of the ['Hello world' programs](#helloworld) to make sure it works.

For more details, please read [General Programming Issues](#generalprogramming) and the sample code files in the distribution
(these should be in 
`C:\Program Files\CryptoSysPKI` or `C:\Program Files (x86)\CryptoSysPKI`). 
There is more [example code](https://cryptosys.net/pki/pkiexamples.html "External link") on our web site.

[[Contents](#topofpage)] [[Index](#index)]

<a id="newinthis"></a>New in this version
-----------------------------------------

Changes in Version 23.0 (September 2024):

* Added the ability to make and read CMS enveloped-data objects using the latest 
RSA Key Encapsulation Mechanism (RSA-KEM) Algorithm `kemRSA` using KEMRecipientInfo.
See [CMS_MakeEnvData](#CMS_MakeEnvData) with option `PKI_KEM_RSA`
and [RSA-KEM](#rsakem).
* Added ability to add a new signer to a CMS signed-data object.
See [CMS_MakeSigData](#CMS_MakeSigData) with option `PKI_ADD_SIGNER`.
* Added key derivation functions KDF2 and KDF3. See [KDF_Bytes](#KDF_Bytes) and [CMS_MakeEnvData](#CMS_MakeEnvData).
* Added ability to use `subjectKeyIdentifier` in CMS signed-data and enveloped-data objects.
See option `PKI_USE_SKI`.
* Made changes to default options when using [CMS_MakeEnvData](#CMS_MakeEnvData).
The default content encryption algorithm is now aes128.
* Changed default output from [CMS_MakeSigData](#CMS_MakeSigData) and [CMS_MakeEnvData](#CMS_MakeEnvData)
to use fixed-length encoding and use strict DER sorting rules for sets.
* Added new features to [CMS_QueryEnvData](#CMS_QueryEnvData) to reflect above changes

    + `kemParams`
        + `ukm`
        + `HASsubjectKeyIdentifier`
        + `recipientIdentifier`
* Added new features to [CMS_QuerySigData](#CMS_QuerySigData) to reflect above changes.

    + `CountOfDigestAlgs`
        + `certificate/N`
        + `HASsubjectKeyIdentifier`
        + `signerIdentifier`

[[Contents](#topofpage)] [[Index](#index)]

<a id="changesearlier"></a>Changes in earlier versions
------------------------------------------------------

Changes in Version 22.1 (1 January 2024):

* Upgraded the random number generator (RNG) to use HMAC_DRBG SHA-512 as per 
NIST Special Publication 800-90A [[SP80090A](#SP80090A)].
This supports increased security strengths up to 256 bits.
* Added support for the RNG functions to use the Intel(R) Digital Random Number Generator (DRNG), 
if available and supported on the user's platform.
The output is used to seed and add entropy to the generator state and Fortuna accumulation pools. It is not used directly.
See [Intel(R) DRNG support](#inteldrng) and [RNG_Initialize](#RNG_Initialize).
* Modified the random number functions that create or update a seed file 
([RNG_MakeSeedFile](#RNG_MakeSeedFile), [RNG_UpdateSeedFile](#RNG_UpdateSeedFile), [RNG_Initialize](#RNG_Initialize))
so that a new seed file is always created even if the file does not exist.
* Increased size of RNG seed file `PKI_RNG_SEED_BYTES` from 64 to 128 bytes.
* Added options to random number functions that prompt for keyboard entropy 
([RNG_MakeSeedFile](#RNG_MakeSeedFile), [RNG_BytesWithPrompt](#RNG_BytesWithPrompt))
to generate an estimated 192 or 256 bits of security strength.
* Added the function [RNG_TestDRBGVS](#RNG_TestDRBGVS) to carry out NIST DRBGVS tests using HMAC_DRBG SHA-512 from [[DRBGVS](#DRBGVS)].

Changes in Version 22.0 (23 October 2023):

* Added support for the safecurve algorithms Ed448 and X448 for EdDSA signatures and ECDH key exchange, respectively.
See [Safe curves for elliptic cryptography](#eccsafecurves) and 
[`ECC_MakeKeys`](#ECC_MakeKeys).

    + Support for the signature algorithm Ed448 is provided for basic signatures using
        	[`SIG_SignData`](#SIG_SignData), CMS signed-data objects using
        	[`CMS_MakeSigData`](#CMS_MakeSigData),
        	and for signing X509 certificates using 
        	[`X509_MakeCert`](#X509_MakeCert).

        + The Diffie-Hellman key exchange algorithm X448 can be used for 
        	[`ECC_DHSharedSecret`](#ECC_DHSharedSecret),
        	and an X448 key can be included in an X.509 certificate using
        	[`X509_MakeCert`](#X509_MakeCert).

* Added support for the AEAD_CHACHA20_POLY1305 authenticated encryption algorithm as per [[RFC8439](#RFC8439)].
This can be used directly with 
[`CIPHER_EncryptAEAD`](#CIPHER_EncryptAEAD)
and in creating a CMS AuthEnvelopedData object using 
[`CMS_MakeEnvData`](#CMS_MakeEnvData).
* Added support for certain Hybrid Public Key Encryption (HPKE) helper functions as per [[RFC9180](#RFC9180)]:
[`HPKE_LabeledExtract`](#HPKE_LabeledExtract),
[`HPKE_LabeledExpand`](#HPKE_LabeledExpand) and
[`HPKE_DerivePrivateKey`](#HPKE_DerivePrivateKey).
See [Hybrid Public Key Encryption (HPKE)](#hybridpke).
* Added the SCRYPT password-based key derivation function from [[RFC7914](#RFC7914)].
See [`PBE_Scrypt`](#PBE_Scrypt) and 
[`PBE_ScryptHex`](#PBE_ScryptHex)
and their equivalent .NET [`Pbe Class`](#mx_Pbe) methods.
* Updated [`ECC_SaveKey`](#ECC_SaveKey) so as to always save private EC keys with the equivalent public key included.

    + Added type `"PKCS8 ONE ASYMMETRIC KEY"` to
        	[`ASN1_Type`](#ASN1_Type)
        	when detecting a PKCS#8 v2 OneAsymmetricKey private key object.

        + Added the option `PKI_KEY_LEGACY` to save safe curve keys (X25519, Ed25519, X448, Ed448) in the older PKCS#8 v1 PrivateKeyInfo form
        	(some applications do not accept the newer v2 form).

* Added an option `PKI_PFX_DOUBLE_ENCRYPT` to create a "double-encrypted" P12/PFX file using
[`PFX_MakeFile`](#PFX_MakeFile) (like P12 files used by SET in Paraguay).
* Modified the output from 
[`ASN1_TextDump`](#ASN1_TextDump)
to display the object lengths more clearly.

Changes in Version 21.0.11 (11 June 2023):

* Fixed [`X509_ReadCertStringFromPFX`](#X509_ReadCertStringFromPFX) to read "double-encrypted" P12/PFX file as issued by CAs in Paraguay.

Changes in Version 21.0 (1 January 2023):

* Added the NIST Secure Hash Algorithm SHA-3 as per [[FIPS202](#FIPS202)] 
with digest lengths 224, 256, 384 and 512 bits to all the 
[Message Digest Hash functions](#hashfunctions)
and their .NET equivalent methods in the
[Hash Class](#mx_Hash).
* Added the SHA-3 family options (HMAC-SHA3-224/256/384/512) to the [HMAC functions](#hmacfunctions)
and their .NET equivalent methods in the
[Hmac Class](#mx_Hmac).
* Added new function [`XOF_Bytes`](#XOF_Bytes) and equivalent .NET method [`Xof.Bytes`](#M_Xof_Bytes)
	to provide eXtendable-Output Functions of any length using SHAKE128 and SHAKE256 as per [[FIPS202](#FIPS202)]
	and MGF1-SHA-* as per [[PKCS#1](#PKCS1)].

* Added new function [`PRF_Bytes`](#PRF_Bytes) and equivalent .NET method [`Prf.Bytes`](#M_Prf_Bytes)
	to produce pseudorandom output of any length using KMAC128 and KMAC256 as per NIST SP800-185 [[SP800-185](#SP800-185)].

* Added Galois/Counter (GCM) mode for [`CIPHER_FileEncrypt`](#CIPHER_FileEncrypt) 
and [`CIPHER_FileDecrypt`](#CIPHER_FileDecrypt) 
(.NET: [`Cipher.FileEncrypt Method`](#M_Cipher_FileEncrypt_StringStringByteByteCipherAlgorithmModePaddingCipher_Opts),
[`Cipher.FileDecrypt Method`](#M_Cipher_FileDecrypt_StringStringByteByteCipherAlgorithmModePaddingCipher_Opts)).
Use this option to encrypt and decrypt files using AES-GCM.

    + AES-GCM mode now also available with
            [`CIPHER_EncryptBytes`](#CIPHER_EncryptBytes),
            [`CIPHER_DecryptBytes`](#CIPHER_DecryptBytes),
            [`CIPHER_EncryptHex`](#CIPHER_EncryptHex) and
            [`CIPHER_DecryptHex`](#CIPHER_DecryptHex).

* Improved checks when encrypting files with [`CIPHER_FileEncrypt`](#CIPHER_FileEncrypt) to prevent input file being
accidentally overwritten.
* Added new function [`CNV_ShortPathName`](#CNV_ShortPathName) to help handle filenames with "International" characters.
See [Filenames with "International" characters](#filenamesinternational).
* Added new C function [`PKI_FormatErrorMessage`](#PKI_FormatErrorMessage) to return a formatted error message string for the last error.
* Added ability to read an RSA public key from a PKCS#10 Certificate Signing Request (CSR) file using [`RSA_ReadAnyPublicKey`](#RSA_ReadAnyPublicKey)
(.NET [`Rsa.ReadPublicKey Method`](#M_Rsa_ReadPublicKey)).
* Added extra attribute types for specifying an [X.509 distinguished name](#distnames): 
`initials`,
`generationQualifier`,
`dnQualifier` and
`pseudonym`.
These complete the list of "SHOULD support" standard attribute types in section 4.1.2.4 of [[RFC5280](#RFC5280)].
* Added option to add a `cRLDistributionPoints` extension to the [X.509 Extensions Parameter](#x509extensions).

Changes in Version 20.6 (10 September 2022):

* Added ability to create CMS EnvelopedData objects using the key management techniques **kekri** and **pwri**.
See 
[`CMS_MakeEnvData`](#CMS_MakeEnvData)
(.NET: [`Cms.MakeEnvData Method`](#M_Cms_MakeEnvData_StringStringStringCipherAlgorithmCms_KeyEncrAlgorithmHashAlgorithmCms_EnvDataOptionsKdf_KdfAlgKdf_KeyWrapAlgStringInt32Cms_ContentEncrAlg)).

    + See also [CMS EnvelopedData objects](#envelopeddata) and [Supported CMS Content Types](#supportedcmstypes).
* Added support for CMS AuthEnvelopedData objects using AES-GCM. See [CMS AuthEnvelopedData objects](#authenvelopeddata).
* Added links to equivalent [Python functions](#UsingWithPython).

Changes in Version 20.5 (18 July 2022):

* Added support to create CMS EnvelopedData objects using the ephemeral-static ECDH standard primitive. See 
[`CMS_MakeEnvData`](#CMS_MakeEnvData)[[`FromBytes`](#CMS_MakeEnvDataFromBytes)][[`FromString`](#CMS_MakeEnvDataFromString)]
(.NET: [`Cms.MakeEnvData Method`](#M_Cms_MakeEnvData_StringStringStringCipherAlgorithmCms_KeyEncrAlgorithmHashAlgorithmCms_EnvDataOptionsKdf_KdfAlgKdf_KeyWrapAlgStringInt32Cms_ContentEncrAlg))

    + See also [Supported CMS Content Types](#supportedcmstypes).
* Changed meaning of *szSeed* and *nSeedLen* parameters for 
[`CMS_MakeEnvData`](#CMS_MakeEnvData)[[`FromBytes`](#CMS_MakeEnvDataFromBytes)][[`FromString`](#CMS_MakeEnvDataFromString)].
* Added extra queries to [CMS_QueryEnvData](#CMS_QueryEnvData) for KeyAgreement ("kari") types.
* Added more new [VBA Wrapper Functions](#vbawrapperfunctions) including [cmsMakeEnvDataFromBytes](#VB_cmsMakeEnvDataFromBytes) and 
[cmsMakeSigDataFromBytes](#VB_cmsMakeSigDataFromBytes).
* Added support for [Key Derivation Functions](#kdffunctions) using the ANSI-X9.63-KDF key derivation function and the HMAC-based Key Derivation Function (HKDF).
See [KDF_Bytes](#KDF_Bytes) and [KDF_ForCms](#KDF_ForCms).
* Added ability to use internal key strings with [X509_MakeCert](#X509_MakeCert) for the private and public keys.
* Added option to add an `smimeCapabilities` extension to an X.509 certificate. See [X.509 Extensions Parameter](#x509extensions).
* Added support for "AES256-SHA256" encryption when creating and reading PFX files with [PFX_MakeFile](#PFX_MakeFile) and [RSA_ReadAnyPrivateKey](#RSA_ReadAnyPrivateKey).
* Added [HASH_Length](#HASH_Length) function to get the length of a message digest in bytes.
* Fixed implicit tags encoding issue for the CMS Algorithm Identifier Protection Attribute.

Changes in Version 20.4 (24 April 2022):

* Added support for Elliptic Curve Cryptography (ECC) Brainpool Standard Curves 
`brainpoolP256r1`, `brainpoolP384r1`, and `brainpoolP512r1`.
These ECC curves are supported in X.509 certificates and CMS SignedData objects,
 as well as in the standard ECC key generation and management and signature functions using ECDSA.
* Added advanced-users-only option `PKI_KEY_SECURE_OFF` to 
[`RSA_ReadAnyPrivateKey`](#RSA_ReadAnyPrivateKey),
[`RSA_ReadAnyPublicKey`](#RSA_ReadAnyPublicKey),
[`ECC_ReadPrivateKey`](#ECC_ReadPrivateKey), and
[`ECC_ReadPublicKey`](#ECC_ReadPublicKey).
This is an advanced option to turn off encryption security for internal keys and allow the key strings to be used between separate processes. 
Do not use unless you know what you are doing. It is not available in .NET or C++ (STL) interfaces.

Changes in Version 20.3 (8 January 2022):

* Added new interface for [C++ programmers using STL](#UsingWithCpp). 
No need to allocate or free *any* memory to use the C++ wrapper functions,
just use `std::string` and `std::vector` objects.
* Added new functions [`RSA_MakeKeysXtd`](#RSA_MakeKeysXtd) and [`RSA_SaveEncKey`](#RSA_SaveEncKey)
which simplify the parameters and options when saving encrypted keys.
* Added new function [`CNV_Utf8FromWide`](#CNV_Utf8FromWide) which maps a UTF-16 (wide character) string to a UTF-8-encoded string.
This is specifically for C and C++ programmers using wide (`wchar_t`) characters and strings.
* Added more VBA wrapper functions. See [VBA Wrapper Function List](#vbawrapperfunctionlist).
* Replaced .NET option `X509.OutputOpts.UTF8String` with [`X509.OutputOpts.Unicode`](#T_X509_OutputOpts).
This option will output a distinguished name in Unicode character set (UTF-8 or UTF-16 as appropriate).
* Fixed issue with .NET method [`X509.TextDump`](#M_X509_TextDump) where LDAP option was ignored.
* Withdrew all .NET methods using previously deprecated X509.Options.

    + X509.CertIssuerName Method (String, String, X509.Options)
        + X509.CertRequest Method (String, String, String, String, X509.Options)
        + X509.CertRequest Method (String, String, String, String, String, X509.Options)
        + X509.CertSubjectName Method (String, String, X509.Options)
        + X509.MakeCert Method (String, String, String, String, Int32, Int32, String, String, X509.KeyUsageOptions, String, X509.Options)
        + X509.MakeCertSelf Method (String, String, Int32, Int32, String, String, X509.KeyUsageOptions, String, X509.Options)
        + X509.MakeCRL Method (String, String, String, String, String, String, X509.Options)
        + X509.QueryCert Method (String, String, X509.Options)

Changes in Version 20.2 (3 October 2021):

* Consolidated all the 32-bit and 64-bit VBA declarations and all the wrapper functions into the one module `basCrPKI.bas`.
The old files `basCrPKI64.bas`, `basCrPKI64_32.bas` and `basCrPKIWrappers.bas`
are no longer needed and indeed *must not* be used. See [Using with Classic Visual Basic VB6 and VBA](#UsingWithVB).
* Added extra queries to  [CMS_QuerySigData](#CMS_QuerySigData) 
(.NET [`Cms.QuerySigData Method`](#M_Cms_QuerySigData))
to extract information from CMS signed-data objects,
namely `signatureValue`, `DigestOfSignedAttrs`, `DigestOfeContent` and `signingCertHash`.
* Added specialist option `PKI_CMS_PSEUDOSIG` to [CMS_MakeSigData](#CMS_MakeSigData)
to enable the creation of a "pseudo"
file with the same structure as a SignedData object except the signature is a dummy placeholder.
Using [CMS_MakeSigDataFromSigValue](#CMS_MakeSigDataFromSigValue) with the same option allows the user subsequently to insert
the signature value (created by a third party) into the pseudo file.
In .NET use the 
[`Cms.MakeSigData Method`](#M_Cms_MakeSigData_StringStringStringStringHashAlgorithmCms_SigDataOptions)
with the `Cms.SigDataOptions.PseudoSig` option,
and the [`Cms.MakeSigDataFromPseudo Method`](#M_Cms_MakeSigDataFromPseudo).
* Added new functions
	[`CIPHER_EncryptBytes`](#CIPHER_EncryptBytes) and
	[`CIPHER_DecryptBytes`](#CIPHER_DecryptBytes)
to replace deprecated
	`CIPHER_EncryptBytes2` and
	`CIPHER_DecryptBytes2`.
This has no effect on .NET methods or the VBA wrapper functions (it just gets rid of that "2").
* Streamlined the .NET interface functions to replace some overloads by a single method with default parameters. 
This now requires a minimum of .NET 4.0 (previously .NET 2.0). 
This should have no effect on existing .NET code, but reduces the size of the interface and documentation files.
* Added convenient error message formating functions
[errFormatErrorMessage](#VB_errFormatErrorMessage) (VBA),
[General.FormatErrorMessage Method](#M_General_FormatErrorMessage) (.NET)
* Added the VBA wrapper functions 
[cnvToHex](#VB_cnvToHex),
[cnvFromHex](#VB_cnvFromHex),
[cnvToBase64](#VB_cnvToBase64) and
[cnvFromBase64](#VB_cnvFromBase64)
as shorter synonyms for [cnvHexStrFromBytes](#VB_cnvHexStrFromBytes), etc.,
and to be more consistent with the .NET interface.
* Added the VBA wrapper function [cnvBytesMid](#VB_cnvBytesMid) to provide the same substring functionality with a byte array in VBA as the built-in `Mid` function does for a string.

Changes in Version 20.1 (13 March 2021):

* Consolidated documentation for 100 [VBA wrapper functions](#vbawrapperfunctions). See [Notes on VBA wrapper functions](#notesonvbawrapperfunctions).
* Added [VBA wrapper function details](#vbawrapperfunctionlist) to manual.
* Updated `VB.NET` examples in manual to remove deprecated options.
* Fixed obscure problem when deciphering an empty plaintext string in a compiled native code VB6 executable.

Changes in Version 20.0 (17 October 2020):

* Added support for [Elliptic Curve Diffie-Hellman (ECDH)](#ecdh) with [ECC_DHSharedSecret](#ECC_DHSharedSecret) and 
.NET [`Ecc.DHSharedSecret Method`](#M_Ecc_DHSharedSecret).
* Added support for the [elliptic "safe curve"](#eccsafecurves) algorithms X25519 and Ed25519.
* Added support for Ed25519 to the [SIG_SignData](#SIG_SignData) function.
* Added support for Ed25519 signatures in X.509 certificates. See [X509_MakeCert](#X509_MakeCert).
* Added support for both ECDSA and Ed25519 signatures in CMS (PKCS#7) signed-data objects. See [CMS_MakeSigData](#CMS_MakeSigData).
* Added new [CIPHER_EncryptHex](#CIPHER_EncryptHex) and [CIPHER_DecryptHex](#CIPHER_DecryptHex) functions to carry out block cipher encryption with padding using hex-encoded parameters
(.NET [`Cipher.Encrypt Method`](#M_Cipher_Encrypt_StringStringStringCipherAlgorithmModePaddingCipher_Opts) 
and [`Cipher.Decrypt Method`](#M_Cipher_Decrypt_StringStringStringCipherAlgorithmModePaddingCipher_Opts)).
* Improved support for [RSA_FromXMLString](#RSA_FromXMLString) function 
(.NET [`Rsa.FromXMLString method`](#M_Rsa_FromXMLString_String)) to read XML data with prefixes.
* Added X.509 extension parameter `keyUsage=noncritical` to force keyUsage attributes in a new X.509 certificate to be non-critical.
* Withdrew previously deprecated methods in the .NET interface:

    + General.IsWin64()
        + All methods using Cms.Options (there are better alternatives):
            - Cms.MakeEnvData(string , string , string , Cms.Options)
                - Cms.MakeEnvDataFromString(string , string , string , Cms.Options )
                - Cms.ReadEnvDataToFile(string , string , string , string , Cms.Options )
                - Cms.ReadEnvDataToString(string , string , string , Cms.Options )
                - Cms.MakeSigData(string , string , string , string , Cms.Options )
                - Cms.MakeSigDataFromString(string , string , string , string , Cms.Options )
                - MakeSigDataFromSigValue(string , byte[] ,byte[] contentData, string , Cms.Options )
                - MakeDetachedSig(string , string , string , string , Cms.Options )
        + Obsolete methods to read RSA keys:
            - ReadEncPrivateKey
                - ReadPrivateKeyInfo
                - ReadPrivateKeyFromPFX
                - GetPublicKeyFromCert
        + Methods using Rsa.EncodeFor:
            - EncodeMsg(int , byte[] , Rsa.EncodeFor )
                - DecodeMsg(byte[] , Rsa.EncodeFor )
* Marked all .NET methods using deprecated X509.Options as obsolete 
(instead use an explicit [`SigAlgorithm`](#T_SigAlgorithm) option 
together with specific [`X509.CertOptions`](#T_X509_CertOptions), 
[`X509.CrlOptions`](#T_X509_CrlOptions) or 
[`X509.CsrOptions`](#T_X509_CsrOptions)).

Changes in Version 12.4 (12 May 2020):

* Added support for additional security attributes in signed-data CMS objects using [CMS_MakeSigData](#CMS_MakeSigData)
(.NET [`Cms.MakeSigData Method`](#M_Cms_MakeSigData_StringStringStringStringCms_SigAlgCms_SigDataOptions)).
See [Additional Security Attributes](#additionalsecurityattributes).

    + Use `PKI_CMS_ADD_SIGNINGCERT` (`Cms.SigDataOptions.AddSigningCertificate`) to add an ESS Signing Certificate to the signed attributes.
        + Use `PKI_CMS_ADD_ALGPROTECT` (`Cms.SigDataOptions.AddAlgProtection`) to add an Algorithm Protection Attribute [[RFC6211](#RFC6211)] to the signed attributes.
* Added support with [CMS_VerifySigData](#CMS_VerifySigData) (`Cms.VerifySigData`) to carry out additional validation when 
signed attributes in a CMS signed-data object contain an ESS Signing Certificate or Algorithm Protection Attribute.
* Added new queries `HASsigningCertificate` and `HASalgorithmProtection` 
to [CMS_QuerySigData](#CMS_QuerySigData) (`Cms.QuerySigData`).
* Added new diagnostic function [`PKI_ModuleInfo`](#PKI_ModuleInfo)
(.NET [`General.ModuleInfo Method`](#M_General_ModuleInfo))
to show additional information about the core DLL module, e.g. "Licensed Developer Edition".

Changes in Version 12.3 (6 March 2020):

* Added new function [`RNG_Guid`](#RNG_Guid)
(.NET [`Rng.Guid Method`](#M_Rng_Guid))
to generate a random 36-character Global Unique IDentifier (GUID) string.
* Added options to [X509_MakeCert](#X509_MakeCert) and [X509_CertRequest](#X509_CertRequest) 
when making an X.509 certificate or PKCS#10 Certificate Signing Request
(.NET [`X509.MakeCert Method`](#M_X509_MakeCert)
and 
[`X509.CertRequest Method`](#M_X509_CertRequest))
to do the following:

    + Specify an empty subjectName in X.509 [distinguished names](#distnames).
        + Add `extKeyUsage` extension purposes in the [X.509 Extensions Parameter](#x509extensions), 
        with an option to mark the extension critical.

        + Make an [arbitrary X.509 extension](#arbitraryx509extn) critical.
* Updated the functions [X509_ReadCertStringFromPFX](#X509_ReadCertStringFromPFX)
and [X509_GetCertFromPFX](#X509_GetCertFromPFX) to read certificates in a PKCS#12 (PFX) file encrypted using the
`pbeWithSHAAnd3-KeyTripleDES-CBC` algorithm 
(.NET [`X509.ReadCertStringFromPFX Method`](#M_X509_ReadCertStringFromPFX)
and
[`X509.GetCertFromPFX Method`](#M_X509_GetCertFromPFX)).
* Added the option `PKI_PFX_STRONG_CERT` to the [PFX_MakeFile](#PFX_MakeFile) function to encrypt the certificate in a PKCS#12 (PFX) file using the stronger 
Triple DES encryption algorithm `pbeWithSHAAnd3-KeyTripleDES-CBC`.
(.NET [`StrongCert`](#T_Pfx_Options) option for the [`Pfx.MakeFile Method`](#M_Pfx_MakeFile)).
* Added `PKI_IV_PREFIX` option to [CIPHER_EncryptBytes2](#CIPHER_EncryptBytes2) and [CIPHER_DecryptBytes2](#CIPHER_DecryptBytes2)
to prepend the IV before the ciphertext in the output.
(.NET [`PrefixIV`](#T_Cipher_Opts) option for  
[`Cipher.Encrypt Method`](#M_Cipher_Encrypt_ByteByteByteCipherAlgorithmModePaddingCipher_Opts)
and
[`Cipher.Decrypt Method`](#M_Cipher_Decrypt_ByteByteByteCipherAlgorithmModePaddingCipher_Opts)).
* Added alternative features for C/VBA programmers using [CIPHER_DecryptBytes2](#CIPHER_DecryptBytes2) when removal of padding bytes is involved.
The user can now obtain the exact required length of the decrypted output buffer for ECB and CBC mode.

Changes in Version 12.2 (24 March 2019):

* Added support for plaintext RSA keys represented in JSON Web Key (JWK) format in the functions
[`RSA_ReadAnyPrivateKey`](#RSA_ReadAnyPrivateKey) and
[`RSA_ReadAnyPublicKey`](#RSA_ReadAnyPublicKey)
(.NET [`Rsa.ReadPrivateKey Method`](#M_Rsa_ReadPrivateKey)
and [`Rsa.ReadPublicKey Method`](#M_Rsa_ReadPublicKey)).
The key may be provided either in a JSON file or as a JSON string. No password is required.
See the example in [`RSA_ReadAnyPublicKey`](#RSA_ReadAnyPublicKey).
* Added new functions to create and read CMS signed-data and enveloped-data objects using byte arrays:

    + [`CMS_MakeEnvDataFromBytes`](#CMS_MakeEnvDataFromBytes) 
        	(.NET [`Cms.MakeEnvDataFromBytes Method`](#M_Cms_MakeEnvDataFromBytes))

        + [`CMS_ReadEnvDataToBytes`](#CMS_ReadEnvDataToBytes) 
        	(.NET [`Cms.ReadEnvDataToBytes Method`](#M_Cms_ReadEnvDataToBytes))

        + [`CMS_MakeSigDataFromBytes`](#CMS_MakeSigDataFromBytes) 
        	(.NET [`Cms.MakeSigDataFromBytes Method`](#M_Cms_MakeSigDataFromBytes))

        + [`CMS_ReadSigDataToBytes`](#CMS_ReadSigDataToBytes) 
        	(.NET [`Cms.ReadSigDataToBytes Method`](#M_Cms_ReadSigDataToBytes))
    Use these functions when the data contains non-ASCII characters such as UTF-8-encoded text.

* [`CMS_ReadSigData`](#CMS_ReadSigData) and its string/byte variants now read content from any CMSVersion (previously only version 1).
* Made improvements to [`CMS_MakeSigData`](#CMS_MakeSigData) 
and [`CMS_MakeEnvData`](#CMS_MakeEnvData) to accept lists of X.509 certificates in a PKCS#7 certificate chain file (.p7c/.p7b).
* Added new option [`Cms.ReadOptions`](#T_Cms_ReadOptions) for
[`Cms.ReadSigDataToFile Method`](#M_Cms_ReadSigDataToFile) and
[`Cms.ReadEnvDataToFile Method`](#M_Cms_ReadEnvDataToFile).
This allows the use of the `BigFile` option when reading large CMS files.
* Deprecated methods in the .NET [Cms Class](#mx_Cms) that use the obsolete 
`Cms.Options Enumeration`.

    + **Note:** This will cause CS0618 compiler warnings ('Cms.XXX' is obsolete) if you have used any of the deprecated methods.
        Solution: edit code to choose a preferred overload.

* Added new function [`X509_GetCertCountInP7Chain`](#X509_GetCertCountInP7Chain)
(.NET [`Cms.GetCertCountInP7Chain Method`](#M_X509_GetCertCountInP7Chain))
as a cleaner function to help in extracting X.509 certificates from a PKCS#7 certificate chain file.

Changes in Version 12.1 (17 November 2018):

* Added [AES-GCM authenticated encryption](#authencryptionaad) with new functions 
	[`CIPHER_EncryptAEAD`](#CIPHER_EncryptAEAD) and [`CIPHER_DecryptAEAD`](#CIPHER_DecryptAEAD)
	(.NET [`Cipher.EncryptAEAD Method`](#M_Cipher_EncryptAEAD_ByteByteByteByteAeadAlgorithmCipher_Opts) and
	[`Cipher.DecryptAEAD Method`](#M_Cipher_DecryptAEAD_ByteByteByteByteAeadAlgorithmCipher_Opts)).
* Added new function [`X509_ReadCertStringFromPFX`](#X509_ReadCertStringFromPFX)
	(.NET [`X509.ReadCertStringFromPFX Method`](#M_X509_ReadCertStringFromPFX))
	to extract X.509 certificate details directly from PFX/PKCS12 data into memory.
* Added new function [`X509_ReadCertStringFromP7Chain`](#X509_ReadCertStringFromP7Chain)
	(.NET [`X509.ReadCertStringFromP7Chain Method`](#M_X509_ReadCertStringFromP7Chain))
	to extract X.509 certificate details directly from P7 certificate chain data into memory.
* Added security improvements to [`CMS_ReadEnvData`](#CMS_ReadEnvData) and [`CMS_ReadEnvDataToString`](#CMS_ReadEnvDataToString)
(.NET [`Cms.ReadEnvDataToFile Method`](#M_Cms_ReadEnvDataToFile) and
[`Cms.ReadEnvDataToString Method`](#M_Cms_ReadEnvDataToString)).
* Minor fix to [`ASN1_TextDump`](#ASN1_TextDump) to catch obscure error when parsing random octet strings.
* Deprecated [`CIPHER_Bytes`](#CIPHER_Bytes) function. Use safer functions
[`CIPHER_EncryptBytes2`](#CIPHER_EncryptBytes2) and [`CIPHER_DecryptBytes2`](#CIPHER_DecryptBytes2) instead.
(No effect for .NET methods.)
* Minor changes to 
[`CIPHER_EncryptBytes2`](#CIPHER_EncryptBytes2) and [`CIPHER_DecryptBytes2`](#CIPHER_DecryptBytes2) 
to handle NULL and zero-length inputs more consistently.
* Updated VBA/VB6 examples in manual to show how to cope with [zero-length bytes arrays](#passemptybytearray) and 
	the proper way to [pass a reference to an empty byte array](#passemptybytearray) (Hint: do not use vbNull like we used to do).

Changes in Version 12.0 (20 June 2018):

* TL;DR: added support for RSA-PSS and RSA-OAEP wherever it is needed; and support for ECDSA in X.509 certificates; and ZLIB compression.
* Added support for RSA-PSS and ECDSA signatures in X.509 certificates, certificate revocation lists (CRL) and PKCS#10 certificate signing requests (CSR)

    + X.509 certificates: [`X509_MakeCert`](#X509_MakeCert)
        	(.NET  
        	[`X509.MakeCert Method`](#M_X509_MakeCert)).

        + X.509 certificate revocation lists: [`X509_MakeCRL`](#X509_MakeCRL),
        	(.NET
        	[`X509.MakeCRL Method`](#M_X509_MakeCRL)).

        + PKCS#10 certificate signing requests: [`X509_CertRequest`](#X509_CertRequest)
        	(.NET
        	[`X509.CertRequest Method`](#M_X509_CertRequest)).

        + Verify any of the above: [`X509_VerifyCert`](#X509_VerifyCert)
        		(.NET
        		[`X509.VerifyCert Method`](#M_X509_VerifyCert)).

        + Validate an X.509 certificate path: [`X509_ValidatePath`](#X509_ValidatePath)
        	(.NET
        	[`X509.ValidatePath Method`](#M_X509_ValidatePath)).

* Added support for RSA-PSS signatures using the [SIG functions](#sigfunctions) and [Sig Class](#mx_Sig)

    + [`SIG_SignData`](#SIG_SignData), [`SIG_SignFile`](#SIG_SignFile),
        	[`SIG_VerifyData`](#SIG_VerifyData), and [`SIG_VerifyFile`](#SIG_VerifyFile).

        + (.NET 
        	[`Sig.SignData Method`](#M_Sig_SignData),
        	[`Sig.SignFile Method`](#M_Sig_SignFile),
        	[`Sig.VerifyData Method`](#M_Sig_VerifyData),
        	[`Sig.VerifyFile Method`](#M_Sig_VerifyFile)).

* Added support for RSA-PSS in CMS signed-data objects using [`CMS_MakeSigData`](#CMS_MakeSigData) and [`CMS_VerifySigData`](#CMS_VerifySigData)
(.NET 
[`Cms.MakeSigData Method`](#M_Cms_MakeSigData_StringStringStringStringHashAlgorithmCms_SigDataOptions),
[`Cms.VerifySigData Method`](#M_Cms_VerifySigData)).
* Added support for RSA-OAEP in CMS enveloped-data objects using [`CMS_MakeEnvData`](#CMS_MakeEnvData) and [`CMS_ReadEnvData`](#CMS_ReadEnvData)
(.NET 
[`Cms.MakeEnvData Method`](#M_Cms_MakeEnvData_StringStringStringCipherAlgorithmCms_KeyEncrAlgorithmHashAlgorithmCms_EnvDataOptionsKdf_KdfAlgKdf_KeyWrapAlgStringInt32Cms_ContentEncrAlg),
[`Cms.ReadEnvDataToFile Method`](#M_Cms_ReadEnvDataToFile)).
* Added new functions [`RSA_Encrypt`](#RSA_Encrypt) and [`RSA_Decrypt`](#RSA_Decrypt) 
	(.NET [`Rsa.Encrypt Method`](#M_Rsa_Encrypt) and
	[`Rsa.Decrypt Method`](#M_Rsa_Decrypt))
	to encrypt and decrypt short messages using
	the RSA encryption schemes from PKCS#1, including RSAES-OAEP.

* Public ECC keys can now be read directly from an X.509 certificate with [`ECC_ReadPublicKey`](#ECC_ReadPublicKey) 
	(.NET [`Ecc.ReadPublicKey Method`](#M_Ecc_ReadPublicKey)).

* Added ability to use unencrypted private key file with [`X509_MakeCert`](#X509_MakeCert) and [`X509_CertRequest`](#X509_CertRequest)
	(.NET [`X509.MakeCert Method`](#M_X509_MakeCert),
	[`X509.CertRequest Method`](#M_X509_CertRequest)).

* Added ability to self-verify a PKCS#10 Certificate Signing Request (CSR) using [`X509_VerifyCert`](#X509_VerifyCert)
	(.NET 
	[`X509.VerifyCert Method`](#M_X509_VerifyCert)).

* Added ability to add an arbitrary RDN to an X.509 distinguished name when creating an X.509 certificate of certificate signing request. 
	See [Specifying an arbitrary RDN in a distinguished name](#arbitraryrdn).

    + Also added ability to use an escaped hex sequence (`\<hex><hex>`) to insert 8-bit octets in an attribute value, 
        	see [Specifying Distinguished Names](#distnames).

* Added ability to add an arbitrary Extension to an X.509 v3 certificate using [`X509_MakeCert`](#X509_MakeCert)
	(.NET [`X509.MakeCert Method`](#M_X509_MakeCert)).	
	See [Add an arbitrary X.509 Extension](#arbitraryx509extn). This allows you, for example, to add a video of your cat to an X.509 certificate :-).

* Added "hashAlgorithm" and "pssParams" queries to [`X509_QueryCert`](#X509_QueryCert) (useful for checking the parameters of RSA-PSS signatures).
* Added [`COMPR_Compress`](#COMPR_Compress) and [`COMPR_Uncompress`](#COMPR_Uncompress) functions
	to compress and uncompress data using zlib compression
	(.NET [`Compr.Compress Method`](#M_Compr_Compress)
	and [`Compr.Uncompress Method`](#M_Compr_Uncompress)).

* Improved performance of [`WIPE_File`](#WIPE_File) 
	(.NET [`Wipe.File Method`](#M_Wipe_File)), 
	and added option to overwrite with a single pass of zero bytes (quicker but less secure).

* Added [`X509_TextDumpToString`](#X509_TextDumpToString) function 
	(.NET [`X509.TextDumpToString Method`](#M_X509_TextDumpToString)) 	
	to dump details of X.509 certificate (or a CRL or a PKCS#10 CSR) directly to a string.

* Added [`ASN1_TextDumpToString`](#ASN1_TextDumpToString) function 
	(.NET [`Asn1.TextDumpToString Method`](#M_Asn1_TextDumpToString)) 		
	to dump details of ASN.1 formatted data directly to a string.

* Replaced the anomalous +1/-1 return values for [`X509_VerifyCert`](#X509_VerifyCert), [`X509_ValidatePath`](#X509_ValidatePath),
	[`X509_CheckCertInCRL`](#X509_CheckCertInCRL), and [`X509_CertIsValidNow`](#X509_CertIsValidNow) with consistent error codes.
	All these functions now return 0 on success (as before) or a specific nonzero [error code](#errorcodes) on failure. 
	More details of any error can usually be found using [`PKI_LastError`](#PKI_LastError).

* Deprecated methods in the .NET [X509 Class](#mx_X509) that use the confusing grab-bag `X509.Options Enumeration`.
* Withdrew deprecated functions `CIPHER_EncryptBytesPad` and `CIPHER_DecryptBytesPad`. Use instead
	[`CIPHER_EncryptBytes2`](#CIPHER_EncryptBytes2) and
	[`CIPHER_DecryptBytes2`](#CIPHER_DecryptBytes2).
	This has no effect on .NET methods.

* Withdrew deprecated method `Pfx.MakeFile` with obsolete Boolean parameter.
* Changed some option flag values, in particular `PKI_SIG_ASN1DER` to avoid clashes. See the defined macros in `diCrPKI.h` and the public constants in `basCrPKI.bas`.
	This is important if you have written an interface that hardcodes the option values. If you use the defined C macros or public VBA constants, it should not be an issue.

Changes in Version 11.2 (8 August 2017):

* Fixed [`ECC_MakeKeys`](#ECC_MakeKeys) and [`ECC_SaveEncKey`](#ECC_SaveEncKey) so "prf" option works in szParams parameter, e.g. "prf=hmacWithSHA256;".
* Added [`RSA_ToXMLStringEx`](#RSA_ToXMLStringEx) function 
	(.NET [`Rsa.ToXMLString Method`](#M_Rsa_ToXMLString_StringStringRsa_XmlOptions)) 
	which allows adding namespace prefix before element names, e.g. <ds:RSAKeyValue>.
* Added [`ECC_KeyHashCode`](#ECC_KeyHashCode) function 
	(.NET [`Ecc.KeyHashCode Method`](#M_Ecc_KeyHashCode))
	to give a 32-bit hash value for an ECC private or public key.
* Added [`PKI_Platform`](#PKI_Platform) function 
	(.NET [`General.Platform Method`](#M_General_Platform))	
	to give operating platform "Win32" or "X64" directly.
* Fixed LDAP output of distinguished names to use correct hexadecimal form of attribute value if attribute name is in dotted decimal form, as per section 2.4 of RFC 4515.
* Added LDAP and DECIMAL options to [`X509_TextDump`](#X509_TextDump) to display distinguished name in LDAP form and serial number in decimal.
* [`ASN1_TextDump`](#ASN1_TextDump) and [`ASN1_Type`](#ASN1_Type) now accept a plain base64 text file as input.
* Added various .NET method overloads to cope with specialist options.

Changes in Version 11.1 (20 May 2016):

* Added new symmetrical block cipher functions 
	[`CIPHER_EncryptBytes2`](#CIPHER_EncryptBytes2) and
	[`CIPHER_DecryptBytes2`](#CIPHER_DecryptBytes2)
as safer replacements for 
	`CIPHER_EncryptBytesPad` and
	`CIPHER_DecryptBytesPad` (since withdrawn in v12.0)
with explicit checks for lengths of key and IV byte arrays. 
These new safer functions are now used internally in the equivalent .NET [`Cipher class`](#mx_Cipher) methods.

    + *Warning:* These functions now ignore any padding options except the default `NoPadding` for CTR, OFB and CFB modes
        		(formerly the padding would have been added or stripped even though it wasn't needed).

* Added new block cipher functions
	[`CIPHER_FileEncrypt`](#CIPHER_FileEncrypt) and
	[`CIPHER_FileDecrypt`](#CIPHER_FileDecrypt)
as safer replacements for the now-deprecated 
	[`CIPHER_File`](#CIPHER_File)
with explicit checks for lengths of key and IV byte arrays.
In addition, these new functions allow the user to specify the type of padding used for ECB and CBC modes 
(previously only `PKCS5Padding`),
and give the option to prepend the IV to the ciphertext data.

* Added new padding methods `AnsiX923Padding` and `W3CPadding`:
	see [Padding schemes for block ciphers](#paddingschemes).

* Improved constant-time checks when stripping padding from decrypted data.
* Added two new methods 
	[`Cipher.BlockBytes Method`](#M_Cipher_BlockBytes)
	and
	[`Cipher.KeyBytes Method`](#M_Cipher_KeyBytes)
	to return the correct sizes in bytes of the cipher block and key for a given block cipher algorithm.

* Changed the behaviour of the decoding functions 
	[`CNV_BytesFromHexStr`](#CNV_BytesFromHexStr) and
	[`CNV_BytesFromB64Str`](#CNV_BytesFromB64Str)
to be stricter and return an error if any obviously invalid characters are found (formerly they were just ignored).
Whitespace characters are still allowed in both hex and base64 strings, and ASCII punctuation characters in a hex string.
So, for example, the hex string `"DE:AD:BE:EF"` is still OK, 
but characters in the range `[G-Zg-z]` in a hex string now cause an error.

    + *Warning:* This change may break your application if you have assumed the earlier rather lax behaviour
        		(it was probably wrong anyway!).

* Fixed error codes returned by [`PFX_VerifySig`](#PFX_VerifySig).
* Improved parsing of X.509 certificate serial numbers when specified in "#x" hexadecimal form with 
[X.509 Extensions](#x509extensions) and
[`OCSP_MakeRequest`](#OCSP_MakeRequest). 
Space characters and an odd number of hex digits are now accepted correctly.

Changes in Version 11.0 (8 March 2016):

* Added features for [Elliptic Curve Cryptography (ECC)](#eccrypto)

    + Support for NIST curves (P-192, P-224, P-256, P-384 and P-521) and the "Bitcoin" curve `secp256k1`.
        + Generate new EC key pairs, read in and save key files in different formats, and analyze key files.
        + Support for most formats of keys
* Added support for elliptic curve ECDSA signatures in the [`SIG`](#sigfunctions) functions 
	and [`Sig class`](#mx_Sig) methods.

* Simplified options for [saving encrypted private keys](#encryptedkeyoptions).
* Added new byte manipulation utilities:

    1. [`CNV_ReverseBytes`](#CNV_ReverseBytes). For .NET
        	[`Cnv.ReverseBytes`](#M_Cnv_ReverseBytes)

        2. [`CNV_NumFromBytes`](#CNV_NumFromBytes) and [`CNV_NumToBytes`](#CNV_NumToBytes). For .NET
        	[`Cnv.NumFromBytes`](#M_Cnv_NumFromBytes) and [`Cnv.NumToBytes`](#M_Cnv_NumToBytes)

        3. [`CNV_Base58FromBytes`](#CNV_Base58FromBytes) and [`CNV_Base58ToBytes`](#CNV_Base58ToBytes). For .NET
        	[`Cnv.ToBase58`](#M_Cnv_ToBase58) and [`Cnv.FromBase58`](#M_Cnv_FromBase58)

* Added new [hash algorithms](#hashfunctions) useful for Bitcoin calculations: RIPE160-MD, 
	"double" hashes (`HASH(HASH(m))`), 
	and the Bitcoin160 algorithm (`RIPEMD160(SHA256(m))`).

* Added keyUsage options to the [X.509 Extension Parameter](#x509extensions) 
so they can be added to new certificate signing requests using [`X509_CertRequest`](#X509_CertRequest).
* Added facility to specify `serialNumber` as a decimal integer when using the [X.509 Extension Parameter](#x509extensions).
* Fixed [`X509_MakeCert`](#X509_MakeCert) so when importing from an existing certificate signing request (CSR) it will copy
	the exact distinguished name and any keyUsage or subjectAltName extensions in the CSR file.

* Improved [`ASN1_TextDump`](#ASN1_TextDump) and [`X509_TextDump`](#X509_TextDump)
	 to display more information about unexpected ASN.1 objects (i.e., to display the ASN.1 value in hex instead of ignoring it).

* Removed the obsolete UTF-8 `Cnv.CheckUTF8 Method (String)`. 
See [Deprecated and obsolete UTF-8 functions](#utf8andlatin1).
* Minimum required operating platform is now Windows XP and above (that is, XP/2003/Vista/W7/W8/W10/...). 
	Legacy support for W98/NT4/2000 discontinued.

Changes in Version 10.0 (27 March 2015):

* Added functions [`RSA_ReadAnyPrivateKey`](#RSA_ReadAnyPrivateKey)
and [`RSA_ReadAnyPublicKey`](#RSA_ReadAnyPublicKey)
to read private and public keys from almost "any" supported format into an internal key string.
* Added new signature functions [`SIG_SignData`](#SIG_SignData)
and [`SIG_SignFile`](#SIG_SignFile)
to create RSA signatures in one step. 
The output is a base64-encoded string suitable for
a `<SignatureValue>` node in an XML-DSIG document.
* Added new signature verification functions [`SIG_VerifyData`](#SIG_VerifyData)
and [`SIG_VerifyFile`](#SIG_VerifyFile)
to verify RSA signatures in base64-encoded form.
* Added new function [`RSA_KeyValue`](#RSA_KeyValue) to extract a base64-encoded RSA key value from
an internal key string.
The output is a base64-encoded string suitable for a `<RSAKeyValue>` node in an XML-DSIG document.
* Added new functions [`CMS_MakeComprData`](#CMS_MakeComprData)
and [`CMS_ReadComprData`](#CMS_ReadComprData)
to create and read CMS compressed-data (.p7z) files.
* Added new function [`SMIME_Wrap`](#SMIME_Wrap) 
and `[Smime.Wrap](#M_Smime_Wrap)` method
to create an S/MIME file from binary CMS signed-data, enveloped-data and compressed-data objects.
* Added new function [`SMIME_Extract`](#SMIME_Extract)
and `[Smime.Extract](#M_Smime_Extract)` method
to extract the body from an S/MIME file.
* Added new function [`SMIME_Query`](#SMIME_Query)
and `[Smime.Query](#M_Smime_Query)` method
to query an S/MIME file for header information.
* Added functions [`ASN1_TextDump`](#ASN1_TextDump) 
and [`ASN1_Type`](#ASN1_Type) to analyze and check the type of ASN.1 objects.
The corresponding .NET methods are
`[Asn1.TextDump Method](#M_Asn1_TextDump)`
and `[Asn1.Type Method](#M_Asn1_Type)`.
* Added feature to set extra fields 
like `dNSName`, `URI` and `iPAddress`
for subject alternative names
in new X.509 certificates and certificate signing requests made using
the [`X509_MakeCert`](#X509_MakeCert), [`X509_MakeCertSelf`](#X509_MakeCertSelf) 
and [`X509_CertRequest`](#X509_CertRequest) functions.
See [X.509 Extensions Parameter](#x509extensions).
* Added feature to extract all the X.509 certificates in a PFX file to a PKCS#7 certificate chain file (.p7c or .p7b) 
using the `PKI_PFX_P7CHAIN` option with the [`X509_GetCertFromPFX`](#X509_GetCertFromPFX) function
or new `[X509.GetP7ChainFromPFX](#M_X509_GetP7ChainFromPFX)` method.
* Added the `PKI_CMS_BIGFILE` option to the [`CMS_MakeSigData`](#CMS_MakeSigData),
[`CMS_ReadSigData`](#CMS_ReadSigData) and [`CMS_VerifySigData`](#CMS_VerifySigData) functions
to process large signed-data files more efficiently.
* Removed the following .NET methods with the obsolete boolean *inputIsBase64* parameter:
    > ```

    > Cms.QueryEnvData Method (String, String, Boolean)
        > Cms.QuerySigData Method (String, String, Boolean)
        > Cms.GetSigDataDigest Method (String, String, Boolean)
        > Cms.ReadSigDataToFile Method (String, String, Boolean)
        > Cms.ReadSigDataToString Method (String, Boolean)
        > Cms.VerifySigData Method (String, String, String, Boolean)

    > ```

Changes in Version 3.10 (2 September 2014):

* Added the functions `CIPHER_EncryptBytesPad` 
and `CIPHER_DecryptBytesPad` which use the specified block cipher algorithm,
mode and padding to encrypt and decrypt data in a byte array. Padding is added if required before encryption and removed after decryption.
The equivalent .NET methods are
`Cipher.Encrypt Method` and `Cipher.Decrypt Method`
* Added the option of using "OneAndZeroes" padding to the [`PAD_*`](#padfunctions) functions
and `Cipher.Pad` 
and `Cipher.Unpad` methods.
* Added the password-based encryption functions [`PBE_Kdf2`](#PBE_Kdf2) 
and [`PBE_Kdf2Hex`](#PBE_Kdf2Hex) to derive a key of any length from a password using the PBKDF2 algorithm
from PKCS#5.
The equivalent .NET methods are 
`[Pbe.Kdf2](#M_Pbe_Kdf2_Int32ByteByteInt32HashAlgorithm)` and 
`[Pbe.Kdf2 (Int32, String, String, Int32)](#M_Pbe_Kdf2_Int32StringStringInt32HashAlgorithm)`.
* Added the .NET methods 
`[Cms.MakeEnvData Method](#M_Cms_MakeEnvData_StringStringStringCipherAlgorithmCms_EnvDataOptions)
(String, String, String, CipherAlgorithm, Cms.EnvDataOptions)` 
and 
`[Cms.MakeEnvDataFromString Method](#M_Cms_MakeEnvDataFromString_StringStringStringCipherAlgorithmCms_EnvDataOptions)
(String, String, String, CipherAlgorithm, Cms.EnvDataOptions)`
to simplify using AES as the content encryption algorithm.
* Changed [`PKI_Version`](#PKI_Version) to return a five-digit number of the form
`Major * 10000 + Minor * 100 + Release`. For example, version 3.10.1 will return the number 31001
whereas version 3.9.4 would have returned 394.

Changes in Versions 3.9.1 to 3.9.4 (4 October 2012 to 9 October 2013):

* Changed behaviour of [`RNG_Initialize`](#RNG_Initialize)
to *always* create a new seed file, even if one does not exist 
(the previous behaviour was to fail with an error if the seed file did not exist).
* Improved the speed of the SHA-512 and SHA-384 functions.
* Minor update to fix problem with random number generator which would cause problems when called from a Windows dialog box.
* Minor update to fix truncation of X.509 serial number when using `PKI_X509_DECIMAL` option in 
[`X509_CertSerialNumber`](#X509_CertSerialNumber) and
[`X509_QueryCert`](#X509_QueryCert).
* Minor updates to fix memory heap read issues with CRL and Latin-1 functions (thanks to Alexandr M.).
* Fixed problem reading `rc2CBC` mode in [`CMS_ReadEnvData`](#CMS_ReadEnvData).

Changes in Version 3.9 (8 September 2012):

* Added the option `PKI_X509_LDAP` to the functions
[`X509_CertIssuerName`](#X509_CertIssuerName), 
[`X509_CertSubjectName`](#X509_CertSubjectName) and
[`X509_QueryCert`](#X509_QueryCert)
	
to display the distinguished name in LDAP string form as per [[RFC4514](#RFC4514)].
This is intended to help users who wish to create an `<X509IssuerName>` or `<X509SubjectName>` element
within an `<X509Data>` in an XML-DSIG document. 
For more details see [LDAP String Representation of Distinguished Names](#ldapstring).
* Added the option `PKI_X509_DECIMAL` to the functions
[`X509_CertSerialNumber`](#X509_CertSerialNumber) and
[`X509_QueryCert`](#X509_QueryCert)
to display the serial number in decimal form instead of hexadecimal.
Use to create an `<X509SerialNumber>` element in XML-DSIG.
* Added extra codes `STREET`, `UID`, `GN` and `TITLE` to supported attribute types
when [specifying a distinguished name](#distnames) for an X.509 certificate.
* Added extra options `encryptedContent`,
`iv` and `encryptedKey`
to [`CMS_QueryEnvData`](#CMS_QueryEnvData).
* Fixed problem with dates for X.509 certificates created on 29 February using 
`[X509_MakeCert](#X509_MakeCert)[[Self](#X509_MakeCertSelf)]`.
* Added SHA-224 to [`RSA_EncodeMsg`](#RSA_EncodeMsg) in `PKI_EMSIG_PKCSV1_5` mode.

Changes in Version 3.8 (14 January 2012):

* Improved the way PFX (PKCS-12) files are handled. Changed the behaviour of 
[`PFX_MakeFile`](#PFX_MakeFile) so it now creates PFX files in the *exact* format that OpenSSL creates
with weak 40-bit encryption of the certificate as default behaviour.
* Added the [`RSA_ReadPrivateKeyFromPFX`](#RSA_ReadPrivateKeyFromPFX) function to read a private key directly from
	a PFX file into an internal key string. 
	Note that this is different from the existing [`RSA_GetPrivateKeyFromPFX`](#RSA_GetPrivateKeyFromPFX) function which 
	just extracts the encrypted PKCS-8 file and saves it. We try to use the convention "Read" to mean read-into-internal-string
	and "Get" to mean extract-and-save-as-a-file.

* Changed [`X509_GetCertFromPFX`](#X509_GetCertFromPFX) to cope with encrypted certificates.
* Added the [`RSA_PublicKeyFromPrivate`](#RSA_PublicKeyFromPrivate) function to convert an internal private key string
	into a public one. This is useful if you only have a private key file like a PFX file.

* Added or changed the corresponding .NET methods to suit the above functions:

    + [Pfx.MakeFile Method](#M_Pfx_MakeFile)
        		with new [Pfx.Options](#T_Pfx_Options)

        + [Rsa.ReadPrivateKeyFromPFX Method](#M_Rsa_ReadPrivateKeyFromPFX)
        + [X509.GetCertFromPFX Method](#M_X509_GetCertFromPFX)
        + [Rsa.PublicKeyFromPrivate Method](#M_Rsa_PublicKeyFromPrivate)

Changes in Version 3.7 (1 July 2011):

* Added the function [`CNV_CheckUTF8File`](#CNV_CheckUTF8File) to check if a file 
contains valid UTF-8 characters.
* Added the `PKI_CMS_BIGFILE` option to the [`CMS_MakeEnvData`](#CMS_MakeEnvData) 
and [`CMS_ReadEnvData`](#CMS_ReadEnvData) to process large enveloped-data files more efficiently.
This option allows, in theory, files of unlimited length to be enveloped. 
In addition, the 16 MB limit on the usual mode has been removed.
* Changed the behaviour of the [`CMS_MakeEnvData`](#CMS_MakeEnvData) function
to fail if *any* of the specified certificate files are missing or corrupted.
* Removed the restriction on the number of recipients allowed in 
`[CMS_MakeEnvData](#CMS_MakeEnvData)[[FromString](#CMS_MakeEnvDataFromString)]`.
* Removed the requirement to specify the `PKI_CMS_FORMAT_BASE64`/`inputIsBase64` option in
functions that read base64-encoded CMS files like 
[`CMS_ReadEnvData`](#CMS_ReadEnvData), 
[`CMS_ReadSigData`](#CMS_ReadSigData),
[`CMS_QueryEnvData`](#CMS_QueryEnvData) and
[`CMS_QuerySigData`](#CMS_QuerySigData).
These functions (and their .NET equivalents) will now detect the encoding of the input file automatically.
* Added new overloads to the methods in the [Cms Class](#mx_Cms) to reflect new or obsolete options.
Added the `Cms.SigDataOptions` enumeration to provide advanced options and 
complement the `Cms.EnvDataOptions` enumeration.
* Fixed issues where some of the more exotic option combinations for 
[`CMS_MakeEnvData`](#CMS_MakeEnvData) and
[`CMS_MakeSigData`](#CMS_MakeSigData)
were meant to use SHA-2 but didn't.
* Fixed issue where certain obscure inputs to the raw RSA functions would cause a GPF error.
* Tweaked the format of the public key file created using the `PKI_FORMAT_SSL` option when using
[`RSA_MakeKeys`](#RSA_MakeKeys) and [`RSA_SavePublicKey`](#RSA_SavePublicKey).
The file is now saved in the exact same format as OpenSSL; i.e. "Unix" line endings and a line-length of 64 characters. 
This is specifically to help users in Portugal with
the peculiar standards enforced by the DGCI (and should not make any difference to other users).

Changes in Version 3.6 (25 August 2010):

* Added new padding functions 
	[`PAD_BytesBlock`](#PAD_BytesBlock) and
	[`PAD_HexBlock`](#PAD_HexBlock)
	to provide PKCS#5/#7 padding to encryption blocks and the equivalent functions to remove the padding,
	[`PAD_UnpadBytes`](#PAD_UnpadBytes) and
	[`PAD_UnpadHex`](#PAD_UnpadHex). 
	The corresponding .NET methods are 
	[Cipher.Pad](#M_Cipher_Pad_ByteCipherAlgorithmPadding) and
	[Cipher.Unpad](#M_Cipher_Unpad_ByteCipherAlgorithmPadding).
* Added new functions 
	[`CNV_Latin1FromUTF8Bytes`](#CNV_Latin1FromUTF8Bytes) and
	[`CNV_UTF8BytesFromLatin1`](#CNV_UTF8BytesFromLatin1)
	to handle UTF-8 encoded data correctly using byte arrays instead of strings.
	These replace the deprecated functions 
	`CNV_Latin1FromUTF8` and
	`CNV_UTF8FromLatin1`.
* Added the new function [`CNV_CheckUTF8Bytes`](#CNV_CheckUTF8Bytes), and the corresponding method
	`Cnv.CheckUTF8(Byte[])` to replace the deprecated `CNV_CheckUTF8`
	and Cnv.CheckUTF8(String).
	See also [UTF-8 and Latin-1](#utf8andlatin1).
* Added the new function [`CNV_ByteEncoding`](#CNV_ByteEncoding) and equivalent method
	[Cnv.ByteEncoding](#M_Cnv_ByteEncoding) to convert encoding in a byte array between UTF-8 and Latin-1.
* Added new .NET methods to handle base64 strings in a safe manner and to convert directly between hex and base64 encodings: 
	[Cnv.FromBase64](#M_Cnv_FromBase64),
	[Cnv.ToBase64](#M_Cnv_ToBase64_Byte),
	[Cnv.Base64Filter](#M_Cnv_Base64Filter),
	[Cnv.Base64FromHex](#M_Cnv_Base64FromHex),
	[Cnv.HexFromBase64](#M_Cnv_HexFromBase64), and
	[Cnv.StringFromBase64](#M_Cnv_StringFromBase64).
* Added a full set of `VB.NET` examples to this manual with cross references (since removed).
* Improved the level of detail for all [.NET Classes and Methods](#dotnetsummary) with full cross references to the
	new examples and the equivalent VB6/C functions.
* Fixed issue with [CNV_HexFilter](#CNV_HexFilter) and non-ASCII characters,
* Improved the way the [Secure Random Number Generator](#rnginfo) gathers entropy across threads.

Changes in version 3.5 (2 May 2010):

* Added the [`X509_MakeCRL`](#X509_MakeCRL) function to make a basic X.509 certificate revocation list (CRL).
* Added the [`X509_CheckCertInCRL`](#X509_CheckCertInCRL) function to check if a given X.509 certificate
has been revoked in an X.509 certificate revocation list (CRL).
* Added the [`OCSP_MakeRequest`](#OCSP_MakeRequest) function to 
create an Online Certification Status Protocol (OCSP) request as a base64 string.
* Added the [`OCSP_ReadResponse`](#OCSP_ReadResponse) function to 
read a response to an Online Certification Status Protocol (OCSP) request and output the main results in text form.
* Added the [`X509_TextDump`](#X509_TextDump) function to dump details of X.509 certificate (or a CRL or a PKCS10 CSR) to a text file.
* Added the [`X509_ValidatePath`](#X509_ValidatePath) function to validate a certificate path, either in the form of
a list of X.509 certificate filenames or in a PKCS7 "certs-only" certificate chain file (.p7b or .p7c).
* Updated the [`X509_MakeCert`](#X509_MakeCert) function 
to allow the creation of a new X.509 certificate using a PKCS#10 Certificate Signing Request (CSR).
* Updated the [`X509_VerifyCert`](#X509_VerifyCert) function 
to also verify X.509 Certificate Revocation List (CRL) and PKCS#10 Certificate Signing Request (CSR) documents.
* Added more options to the [`X509_QueryCert`](#X509_QueryCert) function.
* Improved the options for input to the 
	`[CMS_ReadEnvData](#CMS_ReadEnvData)[[ToString](#CMS_ReadEnvDataToString)]` and
	`[CMS_ReadSigData](#CMS_ReadSigData)[[ToString](#CMS_ReadSigDataToString)]`
	functions, allowing the user to pass the data directly as a [base64 string or PEM string](#cmsbase64pem); 
	and added the automatic detection of format for input files.

Changes in version 3.4 (19 December 2009):

* All DLL executables are now signed with our code authentication certificate.
* Added functions to detect the platform of the underlying DLL. See [Detecting Win32 or X64 platform](#detectingplatform),
General.IsWin64 Method and [General.Platform Method](#M_General_Platform).
* Removed RSA-KEM functions.
* Updated this manual with the [List of .NET Methods](#methodlist) and
	[Cross-reference between Functions and .NET Methods](#xrefdotnet).

Changes in version 3.3 (19 February 2009):

* Compiled using VS2008 for both Win32 and X64.
* Added the ability to include more [extensions](#x509extensions) and other features to new X.509 certificates
when using the
[`X509_MakeCert`](#X509_MakeCert) and
[`X509MakeCertSelf`](#X509_MakeCertSelf) functions,
and added more options for [distinguished names](#distnames).
* Added the 
[`PEM_FileFromBinFile`](#PEM_FileFromBinFile) and 
[`PEM_FileToBinFile`](#PEM_FileToBinFile)
	functions to enable you to convert files between ASN.1 DER/BER binary format and PEM format.

* Incorporated a faster [BigDigits](http://www.di-mgt.com.au/bigdigits.html "External link") mathematics algorithm 
to speed up RSA modular exponential calculations.
* Improved the performance of the [`WIPE_File`](#WIPE_File) function 
- up to three times faster for large files.
* Amended the
[`RSA_FromXMLString`](#RSA_FromXMLString)
function to allow the import of a restricted RSA private key from XML data consisting only of the 
`<Modulus>`, `<Exponent>` and `<D>` fields.
The resulting "internal" key string can be used to sign raw data but cannot be saved in a private key file.
This is useful to reproduce certain test vectors.
* Added specialist options to enable users to create digital signatures suitable 
for use in an AUTACK message. See [AUTACK messages and ISO/IEC 9796-1 signatures](#autackmsgs).
In particular, this includes

    + Adding a `PKI_EMSIG_ISO9796` option to the [`RSA_EncodeMsg`](#RSA_EncodeMsg) and
        	[`RSA_DecodeMsg`](#RSA_DecodeMsg)
        	functions to enable the user to encode and decode a message according to ISO/IEC 9796-1.

        + Adding a specialist option to the [`RSA_RawPrivate`](#RSA_RawPrivate) and
        	[`RSA_RawPublic`](#RSA_RawPublic)
        	functions to sign and decrypt RSA signatures using the "RSA2" method used in ISO/IEC 9796-1, ANSI X9.31 and P1363.

* Changed the value of `PKI_KEYGEN_INDICATE` option in [`RSA_MakeKeys()`](#RSA_MakeKeys) 
so it does not clash with the des-EDE3-CBC block cipher option.

Changes in version 3.2 (2 February 2008):

* Added a new generic [block cipher function](#cipherfunctions) with AES and Triple DES.
See 
	[`CIPHER_Bytes`](#CIPHER_Bytes),
	[`CIPHER_Hex`](#CIPHER_Hex), and
	[`CIPHER_File`](#CIPHER_File).
* Added SHA-224 to the selection of message digest hash functions and
added the [`HASH_HexFromHex`](#HASH_HexFromHex) 
and [`HMAC_HexFromHex`](#HMAC_HexFromHex) functions.
* Added the option to use the newer PKCS#1 signature algorithms `"shaXXXWithRSAEncryption"`
	with SHA-224/256/384/512
for
[`X509_MakeCert`](#X509_MakeCert)[`[Self]`](#X509_MakeCertSelf)
and
[`X509_CertRequest`](#X509_CertRequest).
* Added the ability to make, read and verify CMS signed-data objects using message digest algorithms SHA-224/256/384/512.
See [`CMS_MakeSigData`](#CMS_MakeSigData)[`[FromString]`](#CMS_MakeSigDataFromString).
* Added the ability to make and read CMS enveloped-data objects using the AES-128/192/256 content encryption algorithms.
See [`CMS_MakeEnvData`](#CMS_MakeEnvData)[`[FromString]`](#CMS_MakeEnvDataFromString).
* Added the ability to make and read CMS enveloped-data objects using the RSA-KEM ("Simple RSA")
key encryption algorithm. *[Withdrawn in v3.4]*.
* Added the primitive functions
`RSA_KemWrap` and
`RSA_KemUnwrap` which will wrap (encrypt) and unwrap (decrypt)
secret keying data for a recipient with the recipient's RSA key using the 
RSA-KEM ("Simple RSA") algorithm.
 *[Withdrawn in v3.4]*.
* Added the block cipher key wrap functions 
	[`CIPHER_KeyWrap`](#CIPHER_KeyWrap)
	and [`CIPHER_KeyUnwrap`](#CIPHER_KeyUnwrap)
	using AES-wrap and Triple DES wrap.
* Added options to save and read encrypted private keys with improved security 
using AES-128/192/256 and SHA-224/256/384/512 when using the 
[`RSA_SaveEncPrivateKey`](#RSA_SaveEncPrivateKey) and
[`RSA_ReadEncPrivateKey`](#RSA_ReadEncPrivateKey)
functions.
* Added the ability to pass both X.509 certificate data and RSA private and public key data to the
[X.509](#x509functions) and [RSA](#rsafunctions) functions
using a [PEM-encoded string](#pemstring) instead of a file.
* Improved the handling of enveloped-data objects by adding the 
[`CMS_QueryEnvData`](#CMS_QueryEnvData) function,
and included the ability to pass a [base64- or PEM-encoded](#pemstring) certificate list to 
[`CMS_MakeEnvData`](#CMS_MakeEnvData) and
[`CMS_MakeSigData`](#CMS_MakeSigData).

Changes in version 3.1 (2 August 2007):

* Added the ability to specify any valid UTF-8 characters in a distinguished name, including CJK characters,
	when creating an X.509 certificate with 
	[`X509_MakeCert`](#X509_MakeCert) or [`X509_MakeCertSelf`](#X509_MakeCertSelf).
	See [Specifying Distinguished Names](#distnames) for more details.
* Added the
[`RSA_KeyMatch`](#RSA_KeyMatch) 
function to verify that a pair of RSA private and public key strings are matched.
* Added the functionality to all the [X.509 certificate functions](#x509functions)
	to allow the user to specify an input X.509 certificate as a base64 string instead of using a file.
* Improved the functions that read ASN.1 data to avoid security issues arising from badly-formed data.
* Increased the speed when encrypting large files using 
	[`TDEA_File`](#TDEA_File). 
	To prevent accidental misuse, if an error occurs when using this function, the output file will now not exist.
* *Specialist Option:* Added an alternative TeleTrusT content encryption algorithm to the
	[`CMS_MakeEnvData`](#CMS_MakeEnvData) function to conform with the 
	PKI requirements of the German Health System.

Changes in version 3.0 (27 March 2007):

* Introduced a new, more secure, random number generator (RNG) based on NIST SP800-90
	[[SP80090A](#SP80090A)] and 
	Ferguson and Schneier's "Fortuna" method from *Practical Cryptography*
	[[FERG03](#FERG03)]. See [Random Number Generator](#rnginfo).
* Incorporated extra security by encrypting "internal" RSA key strings to 
	prevent security breaches by accidental disclosure - see [Internal key strings](#internalkeys). 
Added the
[`RSA_KeyHashCode`](#RSA_KeyHashCode) 
function to allow comparison of internal key strings.
* Added the SHA-384 and SHA-512 message digest algorithms to the 
	[`HASH`](#hashfunctions) functions.
* Added the [`HMAC`](#hmacfunctions) functions to compute a keyed hash value,
[`HMAC_HexFromBytes`](#HMAC_HexFromBytes) and
[`HMAC_Bytes`](#HMAC_Bytes).
* Added functions to query an X.509 certificate file
[`X509_KeyUsageFlags`](#X509_KeyUsageFlags) and
[`X509_QueryCert`](#X509_QueryCert).
* Added functions to read in a X.509 certificate file directly as a base64 string and save the string as a file
[`X509_ReadStringFromFile`](#X509_ReadStringFromFile) and
[`X509_SaveFileFromString`](#X509_SaveFileFromString).

Changes in version 2.9 (12 August 2006):

* Introduced the .NET class library as a more convenient and safer interface for C# and `VB.NET` programmers.
Interface source code in C# is included.
* Added the
[`CMS_MakeSigDataFromSigValue`](#CMS_MakeSigDataFromSigValue) 
function to create a SignedData
object directly from a pre-computed signature value.
* Added the 
`CNV_CheckUTF8`	
function to check whether a string contains only valid UTF-8 characters.
* Added CFB, OFB and CTR modes for the Triple DES block cipher. See, for example,
[`TDEA_BytesMode`](#TDEA_BytesMode).
* Added the [`RNG_Number`](#RNG_Number) function to generate
a random number in a given range.
* Various minor improvements in error handling and thread local storage.

Changes in version 2.8 (26 April 2006):

* Added SHA-256 algorithm to [Message Digest Hash](#hashfunctions) functions.
* Added functions to extract X.509 certificates from other file formats: see 
[`X509_GetCertFromP7Chain`](#X509_GetCertFromP7Chain) and
[`X509_GetCertFromPFX`](#X509_GetCertFromPFX).
* Improved handling of CMS [SignedData](#signeddata) objects including new 
[`CMS_VerifySigData`](#CMS_VerifySigData) and
[`CMS_QuerySigData`](#CMS_QuerySigData) functions.
* Added support to verify DSA signatures as well as RSA in CMS signed data objects.
* Removed 'ByRef' parameters `nMajor` and `nMinor` in
	[`PKI_Version`](#PKI_Version).

Changes in version 2.7 (11 December 2005):

* Added syntax for `VB.NET` and C# to this manual.
* [`X509_VerifyCert()`](#X509_VerifyCert)
can now verify certificates signed using DSA.
* Added ability to [`RSA_ReadEncPrivateKey()`](#RSA_ReadEncPrivateKey)
to read PKCS#8 files encrypted with RC2.
* Made minor changes to make
[`CMS_ReadEnvData()`](#CMS_ReadEnvData)
and
[`CMS_ReadEnvDataToString()`](#CMS_ReadEnvDataToString)
more tolerant of different input formats, including adding support to read
data encrypted with RC2.
* Added support for PBES2 password-based encryption for
[`RSA_MakeKeys()`](#RSA_MakeKeys)
and
[`RSA_SaveEncPrivateKey()`](#RSA_SaveEncPrivateKey).
* Added ability to save RSA keys directly in PEM or OpenSSL format when using
[`RSA_MakeKeys()`](#RSA_MakeKeys).
* Added option to save new X.509 certificates in PEM base64 format when using
[`X509_MakeCert()`](#X509_MakeCert)
and
[`X509_MakeCertSelf()`](#X509_MakeCertSelf)
* Added option to encode
distinguished names as `UTF8String` and to decode multi-byte distinguished names
into 8-bit ASCII, if possible.

[[Contents](#topofpage)] [[Index](#index)]

<a id="Conventions"></a>Conventions in this document
----------------------------------------------------

Classic Visual Basic (VB6/VBA) code is shown shaded as follows:

```

Dim strData As String
Dim nRet As Long
strData = "Hello world"
Debug.Print strData
' ... etc

```

Code in C/C++ is shown as:

```

char *str = "Hello world";
printf("%s\n", str);

```

Code in `VB.NET` is shown as:

```

Dim nDataLen As Integer
Dim abData() As Byte
If strData.Length = 0 Then Exit Function
abData = System.Text.Encoding.Default.GetBytes(strData)
nDataLen = abData.Length

```

Code in C# is shown as:

```

// Encrypt in CBC mode using hex strings
keyhex = "737C791F25EAD0E04629254352F7DC6291E5CB26917ADA32";
ivhex = "B36B6BFB6231084E";
plain = "5468697320736F6D652073616D706520636F6E74656E742E0808080808080808";
cipher = "d76fd1178fbd02f84231f5c1d2a2f74a4159482964f675248254223daf9af8e4";
s = Tdea.Encrypt(plain, keyhex, Mode.CBC, ivhex);
Console.WriteLine("CT={0}",s);
Console.WriteLine("OK={0}",cipher);
Debug.Assert(String.Compare(s, cipher, true)==0, "Tdea.Encrypt{Hex,CBC} failed");

```

Code in Python is shown as:

```
>>> from cryptosyspki import *
>>> Gen.version() # "hello world!" for CryptoSys PKI
200600
>>> Hash.hex_from_data(b'abc') # compute SHA-1 hash in hex of 'abc' as bytes
'a9993e364706816aba3e25717850c26c9cd0d89d'

```

Output from code samples is shown as:

```

Result=OK

```

All functions called directly in the CryptoSys PKI Pro toolkit  begin with 3 or 4 capital letters
followed by an underscore "_", e.g.

```

nRet = RSA_ReadPublicKey(rsaReadPublicKey, nKeyLen, strKeyFile, 0)

```

For VBA/VB6 users, there are convenient wrapper functions provided in 
`basCrPKI.bas`
which avoid the complications of having to pre-dimension strings, etc. These function names
begin with lowercase letters and no underscore. 
For example `hmacHexFromBytes` and `rsaReadPublicKey`.

### VBA code demonstrating wrapper functions:

```

' Test case 1 from RFC 2202 and RFC 4231
' Data = "Hi There"
strDigest = hmacHexFromHex("4869205468657265", "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", PKI_HASH_SHA256)
Debug.Print "HMAC-SHA-256=" & strDigest
Debug.Print "CORRECT     =b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"

```

[[Contents](#topofpage)] [[Index](#index)]

<a id="Copyright"></a>Copyright Notice
--------------------------------------

Except where otherwise noted, the CryptoSysTM PKI Pro program, 
its executables, sample source code and this document
were written by David Ireland
and are copyright (c) 2004-25 by DI Management Services Pty Limited t/a CryptoSys, all rights reserved.
They may not be distributed or reproduced separately by any means whatsoever without express permission in writing.
Users holding a valid developer's licence are permitted to distribute the executables as part of a value-added
application according to the terms of their licence.

The latest version of CryptoSys PKI Pro may be obtained
from
<[https://cryptosys.net/pki/](https://cryptosys.net/pki/ "External link")>.

[[Contents](#topofpage)] [[Index](#index)]

<a id="Theory"></a>Theory
-------------------------

There is no theory explained here. We assume you know what you are doing. 
For a good introduction to the concepts, try
William Stallings, *Cryptography and Network Security: Principles and Practice*
[[STAL](#STAL)]. For a more detailed work, see
*Some Examples of the PKCS Standards* by RSA Laboratories [[PKCS-EX](#PKCS-EX)],
an old but still useful guide.
If all else fails, try reading the [primary references](#References) we used.

You are assumed to have a reasonable knowledge of the basics of cryptography and
public key encryption, 
and that you can program in the language of your choice to an advanced standard.

**If you don't understand what this Toolkit does, you shouldn't be using it.**

[[Contents](#topofpage)] [[Index](#index)]

<a id="SupportedAlgorithms"></a>Supported Algorithms
----------------------------------------------------

Please note [A caution about insecure default algorithms](#cautionwithdefaults).

### Public key encryption and signature algorithms

* RSA public key encryption (`"rsaEncryption"`).
* The RSASSA-PKCS1-v1_5 signature algorithms from PKCS#1, namely:

    + `"sha1WithRSAEncryption"` (`RSA-SHA1`) (default)
        + `"sha224WithRSAEncryption"` (`RSA-SHA224`)
        + `"sha256WithRSAEncryption"` (`RSA-SHA256`) [minimum recommended]
        + `"sha384WithRSAEncryption"` (`RSA-SHA384`)
        + `"sha512WithRSAEncryption"` (`RSA-SHA512`)
        + `"md5WithRSAEncryption"` (`RSA-MD5`) [legacy, not recommended for new implementations]
        + `"md2WithRSAEncryption"` [legacy, definitely not recommended]
* The RSASSA-PSS signature algorithm `"rsaPSS"` and the RSAES-OAEP encryption scheme with the following hash algorithms:

    + `"sha1"` (`RSA-PSS-SHA1`)
        + `"sha224"` (`RSA-PSS-SHA224`)
        + `"sha256"` (`RSA-PSS-SHA256`)
        + `"sha384"` (`RSA-PSS-SHA384`)
        + `"sha512"` (`RSA-PSS-SHA512`)
* The ANSI X9.57 signature algorithm `"dsaWithSha1"` and 
DSA public key `"DSAPublicKey"` for verifying X.509 certificates and CMS SignedData objects only 
(but inherited DSS parameters are not supported).

### Elliptic curve cryptography

* The signature algorithms from FIPS-186:

    + `ecdsaWithSHA1` (`ECDSA-SHA1`)
        + `ecdsaWithSHA224` (`ECDSA-SHA224`)
        + `ecdsaWithSHA256` (`ECDSA-SHA256`) [minimum recommended]
        + `ecdsaWithSHA384` (`ECDSA-SHA384`)
        + `ecdsaWithSHA512` (`ECDSA-SHA512`)
* using the following curves over prime fields:

    + `P-192`, also known as `secp192r1` and `prime192v1`
        + `P-224`, also known as `secp224r1`
        + `P-256`, also known as `secp256r1` and `prime256v1` [minimum recommended]
        + `P-384`, also known as `secp384r1`
        + `P-512`, also known as `secp512r1`
        + `secp256k1` (the Bitcoin curve)
        + `brainpoolP256r1` [RFC5639]
        + `brainpoolP384r1` [RFC5639]
        + `brainpoolP512r1` [RFC5639]
* The elliptic "safe curve" algorithms X25519, Ed25519, X448 and Ed448.

### Symmetric block cipher algorithms for content encryption

* `"des-EDE3-CBC"` (default)
* `"aes128-CBC"` [minimum recommended]
* `"aes192-CBC"`
* `"aes256-CBC"`

In addition, the following algorithm can be read by the `CMS_ReadEnvData[ToString]` functions:

* `"rc2CBC"` with 40-bit or 128-bit effective key sizes

### Block cipher algorithms for key wrapping

* `"aes128-Wrap"` (default)
* `"aes192-Wrap"`
* `"aes256-Wrap"`
* `"cms3DESWrap"`

### Message digest hash algorithms

* `"sha1"` or `"sha-1"`  (default)
* `"sha224"`
* `"sha256"` [minimum recommended]
* `"sha384"`
* `"sha512"`
* `"md5"`
* `"md2"`
* `"ripemd160"`

We keep MD2 here so we can reproduce the examples from RSA Laboratories' 1993 paper [[PKCS-EX](#PKCS-EX)]
and to do tests with some (very old) X.509 certificates. 
You are recommended to use at least SHA-256 in new applications.

### HMAC keyed-hash algorithms

For generating HMAC message authentication codes with the `HMAC_` functions.

* `"hmacWithSHA1"`
* `"hmacWithSHA224"`
* `"hmacWithSHA256"` [minimum recommended]
* `"hmacWithSHA384"`
* `"hmacWithSHA512"`
* `"hmacWithMD5"` [legacy, not recommended for new applications]

### Password-based encryption algorithms

These algorithms from PKCS#5 and PKCS#12 can be used to create PKCS#8 encrypted private key files:

* `"pbeWithSHAAnd3-KeyTripleDES-CBC"` (default)
* `"pkcs5PBES2"` using the `pkcs5PBKDF2` key derivation function with encryption algorithms:

    + `"des-EDE3-CBC"`
        + `"aes128-CBC"` [minimum recommended]
        + `"aes192-CBC"`
        + `"aes256-CBC"`
* `"pbeWithMD5AndDES-CBC"` [legacy, not recommended for new applications]
* `"pbeWithMD2AndDES-CBC"` [legacy, not recommended for new applications]
* `"pbeWithSHA1AndDES-CBC"` [legacy, not recommended for new applications]

In addition to those above, the following legacy algorithms can be read by the `RSA_ReadEncPrivateKey` function:

* `"pkcs5PBES2"` using `pkcs5PBKDF2` with `"desCBC"`
* `"pkcs5PBES2"` using `pkcs5PBKDF2` with `"rc2CBC"`
* `"pbeWithSHAAnd128BitRC2-CBC"`
* `"pbeWithSHAAnd40BitRC2-CBC"`
* `"pbeWithMD5AndRC2-CBC"`
* `"pbeWithMD2AndRC2-CBC"`
* `"pbeWithSHA1AndRC2-CBC"`

### RSA Key Formats

* PKCS#8 encrypted private key `"EncryptedPrivateKeyInfo"` (default for private keys)
* PKCS#1 `"RSAPublicKey"` (default for public keys)
* PKCS#8 unencrypted `"PrivateKeyInfo"`
* PKCS#1 unencrypted `"RSAPrivateKey"` (OpenSSL private key file format)
* X.509 `"SubjectPublicKeyInfo"` (OpenSSL public key file format)

The above key values can be passed as (a) a binary DER-encoded ASN.1 file, (b) a text file in PEM format, (c) a string containing the key in [PEM format](#pemstring).

Also supported are RSA private and public keys represented in XML format to XKMS 2.0 [[XKMS](#XKMS)] 
and JSON Web Key (JWK) format [[JWK](#JWK)]. 
For more details, see [Key Storage Format](#Keystorage).

### Elliptic Curve Key Formats

* PKCS#8 encrypted private key `EncryptedPrivateKeyInfo` using `"id-ecPublicKey"` (default for private keys)
* PKCS#8 unencrypted `PrivateKeyInfo`
* `ECPrivateKey` from [[RFC5915](#RFC5915)]
* `SubjectPublicKeyInfo` from [[RFC5480](#RFC5480)] for public keys (default)

These elliptic curve key values can be passed as (a) a binary DER-encoded ASN.1 file, (b) a text file in PEM format, (c) a string containing the key in [PEM format](#pemstring).

### <a id="supportedcmstypes"></a>Supported CMS Content Types

* `EnvelopedData` content type [[RFC5652](#RFC5652)] using key management techniques key transport (ktri), 
key agreement (kari), previously distributed symmetric key-encryption keys (kekri), and password-based key management (pwri).

    + Supported key transport algorithms are the RSA encryption schemes RSAES-PKCS-v1_5 and RSAES-OAEP.
        + The supported key agreement algorithm is the 'standard' ECDH Elliptic Curve Diffie-Hellman scheme using ANSI-X9.63-KDF or HKDF.
            - `dhSinglePass-stdDH-sha*kdf-scheme` aka `ecdhX963KDF-SHA*` (where * is 1, 256, 384, or 512)
                - `dhSinglePass-stdDH-hkdf-sha*-scheme` aka `ecdhHKDF-SHA*` (where * is 256, 384, or 512)
        + For the `RecipientIdentifier` field in ktri and kari types both choices `issuerAndSerialNumber`
        		and `subjectKeyIdentifier` are supported.

        + For kekri and pwri types only one recipientInfo is supported.
        + For pwri types, only the key derivation algorithm PBKDF2 from [[RFC8018](#RFC8018)] and the key encryption algorithm pwriKEK from [[RFC3211](#RFC3211)] are supported.
        + For kekri types, the key encryption algorithms `cms3DESwrap` and `aes*-wrap` are supported (where * is 128, 192, or 256).
        + The optional EnvelopedData fields `OriginatorInfo` and `UnprotectedAttrs` are *not* supported.
* In addition, for `EnvelopedData`, RSA-KEM is supported using the KemRecipientInfo structure (informally "kemri") 
inside a CMS OtherRecipientInfo (ori),
see [RSA-KEM](#rsakem).
* `AuthEnvelopedData` content type [[RFC5083](#RFC5083)] using the same key management types and schemes as for `EnvelopedData` above
using content-encryption algorithms `AES_*_GCM` and `CHACHA20_POLY1305` (where * is 128, 192, or 256).
* `SignedData` content type [[RFC5652](#RFC5652)].

    + Optional signed attributes are supported.
        + "Detached signature" is supported.
        + Degenerate SignedData "certs-only" messages, a.k.a. PKCS#7 certificate chains are supported.
        + The optional SignedData field `UnsignedAttributes` is not supported.
* `CompressedData` content type as per [[RFC3274](#RFC3274)].

Only CMS objects with an `id-data` inner content type are supported.

### X.509 Certificates

* You can create your own X.509 certificates as either Version 1 or Version 3 (default).
* You can create a self-signed CA certificate and use this to create your own internal chain of
signed certificates.
* A Certificate Signing Request (CSR) file can be created to be submitted to the CA of your choice.
* The most commonly used options for X.509 distinguished names are provided: see 
[Specifying Distinguished Names](#distnames).
* Optional key usage extensions and [X.509 Extensions](#x509extensions) can be added.
* X.509 certificate revocation lists (CRLs) can be read and version 1 CRLs can be created.
* Unicode character sets like UniversalString and BMPString are *not* supported, but UTF8 is.

### <a id="unsupportedalgorithms"></a>Unsupported algorithms

These algorithms from [[PKIXALG](#PKIXALG)] are not currently supported:

* Diffie-Hellman keys (`"DHPublicKey"`)
* Key Exchange Algorithm (`"id-keyExchangeAlgorithm"`)

### <a id="Keystorage"></a>Key Storage Format (RSA)

* By default RSA keys are created in binary DER-encoded files with the format

    + `RSAPublicKey` as per PKCS#1 for public keys
        + `EncryptedPrivateKeyInfo` as per PKCS#8 for private keys.
* The base64 "PEM" and "OpenSSL" formats 
and the unencrypted `PrivateKeyInfo` format for private keys are also supported.
* The default action is to save private keys encrypted with a password. Save as the unencrypted
`PrivateKeyInfo` form at your own risk.
* Public keys can be extracted from an X.509 certificate.
* Private keys can be extracted from a PFX (PKCS#12) file, but only if it has been created using algorithms we support 
(no guarantees with these beasts).
* Functions that might be expected to use the key frequently require the key to be read into an internal string first.
The internal key string is an "ephemeral" string of base64 characters valid only for the current session.
* Treat the internal key strings as "blobs" of data. As of version 3.0, they are encrypted with an internal session key.
See [Internal key strings](#internalkeys).
* Be careful with these internal private key strings - use `WIPE_Data` to erase them when no longer needed.
* Use the [`RSA_ToXMLString`](#RSA_ToXMLString) and
[`RSA_FromXMLString`](#RSA_FromXMLString) functions to convert back and forth
between XML and the toolkit's internal string format. Be very careful as the XML private key data is not encrypted.
* *[New in v12.2]* Plaintext RSA keys represented in JSON Web Key (JWK) format can be read in using the functions
[`RSA_ReadAnyPrivateKey`](#RSA_ReadAnyPrivateKey) and
[`RSA_ReadAnyPublicKey`](#RSA_ReadAnyPublicKey).
(.NET [`Rsa.ReadPrivateKey Method`](#M_Rsa_ReadPrivateKey)
and [`Rsa.ReadPublicKey Method`](#M_Rsa_ReadPublicKey)).
The key may be provided either in a JSON file or as a JSON string. No password is required.

### <a id="Keystorage-ecc"></a>Key Storage Format (ECC)

* By default elliptic curve cryptography (ECC) keys are created as DER-encoded files with the format

    + `SubjectPublicKeyInfo` as per [[RFC5480](#RFC5480)] for public keys
        + `EncryptedPrivateKeyInfo` as per PKCS#8 for private keys.
* Other file formats for ECC are available: see [Elliptic Curve Cryptography](#eccrypto).
* Public ECC keys can be read directly from an X.509 certificate *[New in v12.0]*. See [`ECC_ReadPublicKey`](#ECC_ReadPublicKey).

[[Contents](#topofpage)] [[Index](#index)]

<a id="cautionwithdefaults"></a>A caution about insecure default algorithms
---------------------------------------------------------------------------

**CAUTION:** Many of the default algorithms in this Toolkit (originally written nearly 20 years ago) are no longer considered secure. 
You are recommended explicitly to use at least the following minimum-strength algorithms:

| Algorithm | Default | Minimum recommended | Option to use |
| --- | --- | --- | --- |
| Message digest | SHA-1 | SHA-256 | `PKI_HASH_SHA256` |
| HMAC | HMAC-SHA-1 | HMAC-SHA-256 | `PKI_HMAC_SHA256` |
| RSA signature | sha1WithRSAEncryption | sha256WithRSAEncryption | `PKI_SIG_RSA_SHA256` |
| RSA encryption scheme | RSAES-PKCS1-v1_5 | RSAES-OAEP | `PKI_EME_OAEP` |
| Password-based encryption | pbeWithSHAAnd3-KeyTripleDES-CBC | "pkcs5PBES2" using pkcs5PBKDF2 with "aes128-CBC" | `PKI_PBE_PBKDF2_AES128` |
| Symmetric encryption | des-EDE3-CBC | aes128-CBC/AES-128-GCM* | `PKI_BC_AES128/PKI_AEAD_AES_128_GCM` |

* Use the [`CIPHER_EncryptAEAD`](#CIPHER_EncryptAEAD) function or 
[`Cipher.EncryptAEAD Method`](#M_Cipher_EncryptAEAD_ByteByteByteByteAeadAlgorithmCipher_Opts) for AES-GCM.

We did consider changing the default options to reflect the above recommendations, but realised it would break too many existing applications. 
So we've just added warnings to the various parts of the manual, which we know you all read in detail.

<a id="installation"></a>Installation
-------------------------------------

To install on a test or developer system, use the **install.exe** program provided with the distribution. 
This installs the core DLLs in your main Windows system directory and creates copies of all other required files,
including this manual, in the directory 
`C:\Program Files\CryptoSysPKI` (32-bit platforms) 
or `C:\Program Files (x86)\CryptoSysPKI` (64-bit platforms).

To distribute a Licensed Version to your end users, please read the instructions in the file **distrib.txt**.
You do *not* use the `install.exe` program to distribute to end users.
Note that the core DLL file is completely different for the Trial and Developer versions.

**Important:** You *must* use the `install.exe` 
program to install the Trial version on your system
and you
*must* have administrator rights when installing or uninstalling.

To uninstall, use **Start > Control Panel > Programs and Features > CryptoSys PKI Pro Toolkit** (W10/W7/Vista)
or **Start > Settings > Control Panel > Add/Remove Programs > CryptoSys PKI Pro Toolkit** (XP and older)
to remove the application and all associated files.

### Core executable native DLL

The core executable file is **diCrPKI.dll** which is a native Windows DLL. This file must
exist in the library search path on the user's system for *all* programming language interfaces.
The executable `diCrPKI.dll` is *not* registered with Regsvr32 (it can't be). 
The VB6/VBA and C/C++ interfaces access this core executable directly.

### Wrapper DLL for .NET

**diCrSysPKINet.dll** is a .NET Class Library which
allows programming access for C# and `VB.NET` projects to the "unmanaged" core executable using P/Invoke and the `System.Runtime.InteropServices` API. 
This file is referenced from your .NET project. It is *not* registered.
The core native `diCrPKI.dll` file must exist in the library search path. 

For more information on the executables, see [Technical Details](#technicaldetails).

### <a id="win64platform"></a>Win64 (X64) Platform

A separate version of **`diCrPKI.dll`** is provided which is compiled for X64 platforms.
Both the 32-bit and the 64-bit DLLs are installed by the setup on a 64-bit platform. 
Wow64 (Windows-on-Windows 64-bit) will find and use the correct one it needs.
Please refer to our web page [Using CryptoSys PKI Pro on a 64-bit system](https://cryptosys.net/64bit.html "External link") for more details.

The .NET Library DLL is compiled for both 32- and 64-bit platforms.
When compiling your .NET project in MS Visual Studio, make sure you set **Solution Platforms** to **Any CPU**.

### <a id="detectingplatform"></a>Detecting Win32 or X64 platform

This test returns 1 if the core DLL is Win64 (X64) or 0 if Win32:

[`C#`]

```

int n = General.IsWin64();	

```

[`VB.NET`]

```

n = General.IsWin64()	

```

[C/C++]

```

long nRet;
nRet = PKI_LicenceType(PKI_GEN_PLATFORM);

```

To get the platform as a string, either `"Win32"` or `"X64"`, do this:

```

string s = General.Platform();	

```

```

s = General.Platform()

```

```

char buf[6];
nRet = PKI_ModuleName(buf, sizeof(buf)-1, PKI_GEN_PLATFORM);

```

Remember, the "platform" these tests show is the platform of the core DLL that the system is using. 
WoW64 (*Windows-on-Windows 64-bit*) manages 64-bit and 32-bit applications transparently on a Windows 64-bit operating system.

[[Contents](#topofpage)] [[Index](#index)]

<a id="vb6vsvbdotnet"></a>Visual Basic or Visual Basic: VB6 vs `VB.NET`
-----------------------------------------------------------------------

When we refer to "Visual Basic" in this document we probably mean the old "classic" Visual Basic, VB6. 
This language, although very popular but now dropped by MS, is almost completely compatible with Visual Basic for Applications (VBA) 
that still comes with Microsoft Office products like MS Access and Excel.

When we refer to "`VB.NET`" we mean "Visual Basic .NET" or "Visual Basic 2010" or later. 
This is the one with the 50+ MB runtime instead of the 5 MB one for the old VB6.
Everything we do here in `VB.NET` *should* be compatible in principle with every version since it was introduced in 2002
- we don't use any fancy features.
However, the .NET interface is compiled for NET 4.0 and is upwardly compatible. 

It would have been less confusing if MS had chosen a completely different name for the `VB.NET` version instead of "Visual Basic" (like, er, "Java").
The languages look similar (too similar!), but programs need to be approached in a completely different manner, at least when using our stuff.

In CryptoSys PKI Pro there is a completely different set of `VB.NET` (VB2010+) methods 
that can be called using the `VB.NET` wrapper
`diCrSysPKINet.dll`. See the sections marked **.NET Equivalent** under each function
and the [.NET Help File](#dotnethelp).

In general, the function **`FOO_DoThis`** in VB6 is replaced by a method **`Foo.DoThis`** in `VB.NET`.
The arguments and type of return value will be probably be different - there will be fewer arguments and the result is usually just returned directly
without any pre-dimensioning requirements.
Similarly, the same function **`FOO_DoThis`** in C/C++ is replaced by a method **`Foo.DoThis`** in C# 
which is identical to the `VB.NET` method. For a quick guide, see [Converting VB6 to `VB.NET`](#vb6tovbnet).

[[Contents](#topofpage)] [[Index](#index)]

<a id="generalprogramming"></a>General Programming Issues
---------------------------------------------------------

* [Return Values](#ReturnValues)
* ["Hello world" programs](#helloworld)
* [Converting strings to bytes and vice versa](#stringstobytes)
* [Converting VB6 to `VB.NET`](#vb6tovbnet)

### <a id="ReturnValues"></a>Return Values

All the core VB6/C functions in this toolkit return a 32-bit signed integer value, 
that is a `Long` in VB6/VBA and a `long` in C/C++, but an `Integer` in `VB.NET`
and an `int` in C#.
The wrapper functions provided in the [.NET](#dotnetclassesandmethods)
interface behave differently (and more conveniently) - please
refer to the [detailed documentation](#dotnethelp) on that interface.

Functions either 

1. return zero to indicate success or a nonzero error code on failure; or
2. return a positive value to indicate, say, a required length or other value on success, or a negative error code on failure.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="helloworld"></a>"Hello world" programs

The equivalent of the "Hello world" program for CryptoSys PKI Pro is to call the
`[PKI_Version](#PKI_Version)` function. 
If this simple function call works, then it demonstrates that the Toolkit is properly installed (and *vice versa*!). 

Here is some example source code in VB6, C, C# and `VB.NET`, respectively.

```

Public Sub ShowVersion()
   Dim nRet As Long
   nRet = PKI_Version(0, 0)
   Debug.Print "Version=" & nRet
End Sub

```

```

#include <stdio.h>
#include "diCrPKI.h"
int main(void) 
{
   long version;
   version = PKI_Version(NULL, NULL);
   printf("Version=%ld\n", version);
   return 0;
}

```

```

using CryptoSysPKI;
static void ShowVersion()
{
   int ver;
   ver = General.Version();
   Console.WriteLine("Version={0}", ver);
}

```

```

Imports CryptoSysPKI	
Shared Sub ShowVersion()
   Dim ver As Integer
   ver = General.Version()
   Console.WriteLine("Version={0}", ver)
End Sub

```

[[Contents](#topofpage)] [[Index](#index)]

### <a id="stringstobytes"></a>Converting strings to bytes and vice versa

Use these functions to convert a string of text to an unambiguous array of bytes and vice versa.

In **VB6/VBA**, use the `StrConv` function.

```

Dim abData() As Byte
Dim Str As String
Dim i As Long
Str = "Hello world!"
' Convert string to bytes
abData = StrConv(Str, vbFromUnicode)
For i = 0 To UBound(abData)
    Debug.Print Hex(abData(i)); "='" & Chr(abData(i)) & "'"
Next
' Convert bytes to string
Str = StrConv(abData, vbUnicode)
Debug.Print "'" & Str & "'"

```

```

48='H'
65='e'
6C='l'
6C='l'
6F='o'
20=' '
77='w'
6F='o'
72='r'
6C='l'
64='d'
21='!'
'Hello world!'

```

VB6 stores its strings internally in "Unicode" format, two bytes per character,
but the StrConv function will convert to an array of bytes encoded in "ANSI" format using your default code page.

In **`VB.NET`** use `System.Text.Encoding`.

```

Dim abData() As Byte
Dim Str As String
Dim i As Long
Str = "Hello world!"
' Convert string to bytes
abData = System.Text.Encoding.Default.GetBytes(Str)
For i = 0 To UBound(abData)
    Console.WriteLine(Hex(abData(i)) & "='" & Chr(abData(i)) & "'")
Next
' Convert bytes to string
Str = System.Text.Encoding.Default.GetString(abData)
Console.WriteLine("'" & Str & "'")

```

In .NET strings are stored internally in "Unicode" format (UTF-16) and the GetBytes method 
can extract an array of bytes in any encoding you want.

The `.Default` encoding uses the default code page on your system which is usually 
1252 (Western European) but may be different on your setup.
If you want ISO-8859-1 (Latin-1) you can replace 
`.Default` with `.GetEncoding(28591)` 
(code page 28591 is ISO-8859-1 which is identical to Windows-1252 except for characters in the range 0x80 to 0x9F).
Alternatively use `System.Text.Encoding.GetEncoding("iso-8859-1").GetBytes(Str)`.
If you want UTF-8-encoded bytes, use `System.Text.Encoding.UTF8.GetBytes(Str)`.

In **C#**, use `System.Text.Encoding`, which has identical behaviour to the function in `VB.NET`.

```

byte[] abData;
string Str;
int i;
Str = "Hello world!";
// Convert string to bytes
abData = System.Text.Encoding.Default.GetBytes(Str);
for (i = 0; i < abData.Length; i++)
{
	Console.WriteLine("{0:X}", abData[i]);
}
// Convert bytes to string
Str = System.Text.Encoding.Default.GetString(abData);
Console.WriteLine("'{0}'", Str);

```

In **C and C++**, the distinction between a string and an array of bytes is often blurred.
A string is a zero-terminated sequence of `char` types and
bytes are stored in the `unsigned char` type. 
A string needs an extra character for the null terminating character; 
a byte array does not, but it needs its length to be stored in a separate variable
A byte array can can contain a zero (NUL) value but a string cannot.

```

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static void pr_hexbytes(const unsigned char *bytes, int nbytes)
/* Print bytes in hex format + newline */
{
   int i;
   for (i = 0; i < nbytes; i++)
   	printf("%02X ", bytes[i]);
   printf("\n");
}

int main()
{
   char szStr[] = "Hello world!";
   unsigned char *lpData;
   long nbytes;
   char *lpszCopy;

   /* Convert string to bytes */
   /* (a) simply re-cast */
   lpData = (unsigned char*)szStr;
   nbytes = strlen(szStr);
   pr_hexbytes(lpData, nbytes);

   /* (b) make a copy */
   lpData = malloc(nbytes);
   memcpy(lpData, (unsigned char*)szStr, nbytes);
   pr_hexbytes(lpData, nbytes);

   /* Convert bytes to a zero-terminated string */
   lpszCopy = malloc(nbytes + 1);
   memcpy(lpszCopy, lpData, nbytes);
   lpszCopy[nbytes] = '\0';
   printf("'%s'\n", lpszCopy);

   free(lpData);
   free(lpszCopy);

   return 0;
}

```

```

48 65 6C 6C 6F 20 77 6F 72 6C 64 21
48 65 6C 6C 6F 20 77 6F 72 6C 64 21
'Hello world!'

```

The types `char` and `unsigned char`
might be identical on your system, or they might not be.
We strongly recommend that you explictly distinguish between strings and byte arrays in your code by using
the correct type and consistently treating them differently.

If your string is a Unicode string, then it consists of a sequence of `wchar_t` types.
Converting wide-character strings to a sequence of bytes in C is more problematic.
You can either convert the Unicode string directly to a string of bytes (in which case every second byte will be zero for
US-ASCII characters), 
or use the stdlib `wcstombs` function or the Windows `WideCharToMultiByte` function
to convert to a sequence of multi-byte characters (some will be one byte long, some two)
and then convert the multi-byte string to bytes (you can do this with a simple cast).
Each party encrypting and decrypting must agree on which way to do it.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="vb6tovbnet"></a>Converting VB6 to `VB.NET`

To use CryptoSys PKI Pro in `VB.NET`, you call .NET methods instead of VB6 functions.
In almost all cases, a VB6 function like `FOO_Barbaz` is replaced by the .NET method `Foo.Barbaz`.
The .NET methods generally have fewer parameters and different return values than the equivalent VB6 function.
See the [List of .NET Methods](#methodlist) and 
[Cross-reference between Functions and .NET Methods](#xrefdotnet).

*All* methods in `VB.NET` are "all-in-one" stateless methods and do not require the creation of an object. 
They are all called in a one-off manner.

`Long` types in VB6 *must* be changed to `Integer` in `VB.NET`. 
All integers in CryptoSys PKI Pro are 32-bit signed integers.
You will get an exception or garbage results if you use a `VB.NET` `Long` type.

Functions that in VB6 would have output to a pre-dimensioned string or byte array will return that string or byte array directly in `VB.NET`.
For such methods in `VB.NET`, an error condition is indicated by returning an empty string or byte array. 

VB6/VBA

```

ReDim abDigest(PKI_MAX_HASH_BYTES - 1)
nRet = HASH_Bytes(abDigest(0), PKI_MAX_HASH_BYTES, abMessage(0), nMsgLen, PKI_HASH_MD5)

```

`VB.NET`

```

abDigest = Hash.BytesFromBytes(abMessage, HashAlgorithm.Md5)

```

Annotated example:

VB6/VBA

```

 1 Debug.Print "Testing HASH_HexFromHex ..."
 2 Dim strDigest As String
 3 Dim nRet As Long
 4 Dim strData As String
 5 strDigest = String(PKI_SHA1_CHARS, " ")
 6 strData = "616263"
 7 nRet = HASH_HexFromHex(strDigest, Len(strDigest), strData, PKI_HASH_SHA1)
 8 Debug.Print strDigest

```

Comments:

* *Line 5:* Need to pre-dimension the output string `strDigest` or else!
* *Line 7:* Integer error code is returned: `nRet = 0` indicates success (for this function).
* *Line 7:* Use `PKI_HASH_SHA1` flag to specify hash algorithm option.

Output

```

Testing HASH_HexFromHex ...
a9993e364706816aba3e25717850c26c9cd0d89d

```

`VB.NET`

```

 1 Console.WriteLine("Testing HASH_HexFromHex ...")
 2 Dim strDigest As String
 3 ''Dim nRet As Integer
 4 Dim strData As String
 5 ''strDigest = String(PKI_SHA1_CHARS, " ")
 6 strData = "616263"
 7 strDigest = Hash.HexFromHex(strData, HashAlgorithm.Sha1)
 8 Console.WriteLine(strDigest)

```

Comments:

* *Line 3:* Integer error code is not used.
* *Line 5:* No need to pre-dimension the output string.
* *Line 7:* Output is returned directly as a string: `strDigest.Length > 0` indicates success.
* *Line 7:* Use `HashAlgorithm` property to specify hash algorithm option.

[[Contents](#topofpage)] [[Index](#index)]

<a id="UsingWithVB"></a>Using with Classic Visual Basic VB6 and VBA
-------------------------------------------------------------------

To call the CryptoSys PKI Pro functions
from a classic Visual Basic VB6 project or VBA application, 
just add the module `basCrPKI.bas` to your project
(VBA users should delete the first line `Attribute VB_Name = "basCrPKI"`).

*New in [v20.2]:* 
All the 32-bit and 64-bit VBA declarations and all the wrapper functions are now consolidated into the one module `basCrPKI.bas`. 
  
   

**CAUTION:** The old modules `basCrPKI64.bas`, `basCrPKI64_32.bas` and `basCrPKIWrappers.bas`
must not be used and should be deleted from your projects.

The module `basCrPKI.bas` and distribution test code will be found in the VBA sub-directory of the installation folder, typically
`C:\Program Files (x86)\CryptoSysPKI\VBA` (or `C:\Program Files\CryptoSysPKI\VBA` on a 32-bit machine). 

To find the installation folder, use **Start > All Programs > CryptoSysPKI > CryptoSys PKI Reference Files**.

For examples, see the test code provided in the distribution. 

### <a id="corevbavswrappers"></a>Core VBA/VB6 functions vs better wrapper functions

The "raw" core VBA/VB6 functions work in the same way as you would call the native Win32 API functions from VB6.
You must use the correct variable types and must pre-dimension strings and byte arrays that are to receive
output or you will suffer the wrath of the great god Gee-pee-eff.

All the functions that output to a string or byte array, or take input as byte arrays, are now available in much more convenient
[**wrapper functions**](#vbawrapperfunctions). 

Using the wrapper functions means you do not have to worry about the pre-dimensioning and other hassles with passing references to bytes arrays 
described in the following sections.
Instead, go directly to [Notes on VBA wrapper functions](#notesonvbawrapperfunctions).

### <a id="predimensioning"></a>Pre-dimensioning for VB6

To create a string of, say, length 40 characters, do either:

```

Dim sData As String * 40

```

or

```

Dim sData As String
sData = String(40, " ")

```

If you know the output string needs to be the same size as the input, do this:

```

Dim strInput As String
Dim strOutput As String
strInput = "......"
strOutput = String(Len(strInput), " ")

```

To create a byte array of a given length:

```

Dim abData() As Byte
Dim nLen As Long
nLen = 40
ReDim abData(nLen - 1)

```

Note that byte arrays in VBA are indexed from 0 to `nLen - 1`, 
but an array dimensioned as `abData(nLen - 1)` actually has `nLen` elements.

To create a byte array of the same length as an existing array, do this:

```

Dim abOutput() As Byte
ReDim abOutput(Ubound(abInput))

```

### <a id="findlengthbytearray"></a>Find length of byte array

*Traditional method:* To find the length of an existing byte array:

```

nLen = UBound(abData) - LBound(abData) + 1

```

Be careful, as this will cause a run-time error if `abData()` has not been ReDim'd.

*Safer method:*
Use the VBA wrapper function cnvBytesLen.

```

Dim ab() As Byte
Debug.Print cnvBytesLen(ab) ' Expecting 0
ReDim ab(10)    ' NB actually 11 elements (0..10)
Debug.Print cnvBytesLen(ab) ' 11

```

### <a id="zerolengthbytearrays"></a>Zero-length byte arrays in VB6/VBA

To create a byte array with zero length do this

```

Dim abData() As Byte
abData = vbNullString	

```

There is no simple way to redimension a dynamic array that might have a zero length without risking a runtime error. 
The best you can do is as follows.

```

Dim abData() As Byte
Dim nLen as Long
' Compute required length in bytes...
nLen = ComputeLength()  ' returns length, possibly zero
If nLen > 0 Then
    ReDim Preserve abData(nLen - 1)
Else
    abData = vbNullString
End If

```

### <a id="passemptybytearray"></a>Passing a reference to an empty byte array in VB6/VBA

The equivalent in VBA/VB6 of passing a `NULL` argument in C is to use `ByVal 0&`.
Do *not* use `vbNull`. `vbNull` is not the VBA equivalent of `NULL` in C§.

For example, given the following definition 

```

Public Declare Function FOO_Bar Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ...) As Long

```

the correct way to pass a "NULL" pointer for parameter *lpOutput* is as follows

```

nRet = FOO_Bar(ByVal 0&, 0, ...)	' Strictly correct	

```

In this Toolkit, it is generally sufficient to set *nOutBytes* to be 0 and the corresponding *lpOutput* argument will be ignored.
So the following is sufficient.

```

nRet = FOO_Bar(0, 0, ...)	' OK

```

§ We admit we have used `vbNull` in examples for years, believing it to be the equivalent of `NULL` in C.
Fortunately none of the examples caused a problem because if the length is also set to zero then it is ignored.
*[Changed in v12.1]* This manual has now been edited to suit.	

### <a id="otherissuesvb6"></a>Other Issues For VB6/VBA Users

* VB6/VBA 16-bit **`Integer`** and 64-bit **`LongLong`** types are *never* used in CryptoSys PKI Pro.
Only 32-bit **`Long`** types are used.
* If you get an error of the form 
    > ```

    > Compile error: ByRef argument type mismatch

    > ```

    it means you have omitted the "(0)" after a Byte parameter, e.g.

    ```

    Dim abData() As Byte
    ' ...
    nRet = WIPE_Data(abData, nBytes)    ' WRONG: compile error

    ```

    ```

    nRet = WIPE_Data(abData(0), nBytes) ' CORRECT

    ```

### <a id="notesonvbawrapperfunctions"></a>Notes on VBA wrapper functions

Use the [VBA wrapper functions](#vbawrapperfunctions) to avoid the pre-dimensioning issues for functions that output to a string or byte array.

See [VBA Wrapper Function List](#vbawrapperfunctionlist).

No need to make a first pass to find the required length, or pre-dimension the output variable using `String(nChars, " ")` or `ReDim lpOutput(nBytes-1)`,
and then call again (a potentially dangerous sequence of events).
The wrapper functions do it all in one line.

```

Dim curveName As String
Dim alicePrivateKeyHex As String
Dim ourPrivateKey As String
Dim nChars As Long

curveName = "X25519"
alicePrivateKeyHex = "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a"

' The old long way...
nChars = ECC_ReadKeyByCurve(vbNullString, 0, alicePrivateKeyHex, curveName, PKI_ECC_PRIVATE_KEY)
Debug.Assert nChars > 0
ourPrivateKey = String(nChars, " ")
nChars = ECC_ReadKeyByCurve(ourPrivateKey, nChars, alicePrivateKeyHex, curveName, PKI_ECC_PRIVATE_KEY)

' The new short way with a wrapper function
ourPrivateKey = eccReadKeyByCurve(alicePrivateKeyHex, curveName, PKI_ECC_PRIVATE_KEY)

Debug.Assert Len(ourPrivateKey) > 0

```

If the core VBA function name is `FOO_FuncName()`, then the wrapper function will be `fooFuncName()`.

The function `fooFuncName()` will return the output as a string or byte array directly.

If an error occurs, the result will be a zero-length string or array.
Use the [`PKI_ErrorCode`](#PKI_ErrorCode) and `pkiGetLastError()` functions to get more information.

#### Byte array variables

Wrapper functions that output to a byte array return the array directly. No need to ReDim. Input byte arrays are passed directly *without needing the `(0)`*
and without needing to compute the length beforehand.

```

' The old way - we need all the byte array lengths
Dim lpKey() As Byte
Dim lpIV() As Byte
Dim lpPlain() As Byte
Dim lpCipher() As Byte
Dim nBytes As Long
Dim nDataLen As Long
Dim nKeyLen As Long
Dim nIvLen As Long
' Set values for lpPlain, lpKey, lpIV [cut]
nDataLen = cnvBytesLen(lpPlain)
nKeyLen = cnvBytesLen(lpKey)
nIvLen = cnvBytesLen(lpIV)
nBytes = CIPHER_EncryptBytes(ByVal 0&, 0, lpPlain(0), nDataLen, lpKey(0), nKeyLen, lpIV(0), nIvLen, "Aes128/CBC/OneAndZeroes", 0)
Debug.Assert nBytes > 0
ReDim lpCipher(nBytes - 1)
nBytes = CIPHER_EncryptBytes(lpCipher(0), nBytes, lpPlain(0), nDataLen, lpKey(0), nKeyLen, lpIV(0), nIvLen, "Aes128/CBC/OneAndZeroes", 0)

```

With wrapper function:

```

lpCipher = cipherEncryptBytes(lpPlain, lpKey, lpIV, "Aes128/CBC/OneAndZeroes")

```

That's 4 extra variables we don't need, and seven lines of code is reduced to one. 
Note the `(0)` needed in the raw function, e.g. `lpPlain(0)`, is not required with the wrapper function.

#### Empty byte arrays

```

' To pass a "null" (empty) byte array, assign `vbNullString` to the variable.
Dim lpIV() As Byte
lpIV = vbNullString   ' Set to empty array
lpCipher = cipherEncryptBytes(lpPlain, lpKey, lpIV, "Aes128/ECB")

```

Note that you must pass a proper variable that has been Dim'd, you cannot pass `vbNullString` directly for a byte array parameter.

To pass an empty **String** variable you can simply use either the empty string `""` or `vbNullString`.

```

' To pass a "null" IV in hex, just use the empty string
strCipherHex = cipherEncryptHex(strPlainHex, strKeyHex, "", "Aes128/ECB", 0)

```

```

' Or vbNullString
strCipherHex = cipherEncryptHex(strPlainHex, strKeyHex, vbNullString, "Aes128/ECB", 0)

```

[[Contents](#topofpage)] [[Index](#index)]

<a id="UsingWithC"></a>Using with ANSI C
----------------------------------------

To use the "core" ANSI C interface, include the `diCrPKI.h` file with your source code
and link with the `diCrPKI.lib` library. The only non-ANSI C requirement
is that your complier supports the `__stdcall` 
calling convention to call native API functions from a Windows native DLL. 
The sample C code `PKI_Examples.c` provided in the distribution carries out a variety
of tests using known test vectors. There are examples given for most functions.

The "core" VB6/VBA functions and ANSI C functions are identical in form. 
The function names are identical, the arguments are the same 
(even though we may have used different parameter names in the VB and C syntaxes),
and the same warnings given in the Remarks section apply to both.
Just be careful to [add an extra character for output string types](#cusersaddone) in C.

The include file `diCrPKI.h` and distribution test code will be found in the C sub-directory of the installation folder, typically
`C:\Program Files (x86)\CryptoSysPKI\C` (or `C:\Program Files\CryptoSysPKI\C` on a 32-bit machine). 

To find the installation folder, use **Start > All Programs > CryptoSysPKI > CryptoSys PKI Reference Files**.

### <a id="typeconversions"></a>Type Conversions

The following type conversions apply between VB6/VBA and C/C++:-

| VB6/VBA | C/C++ |
| --- | --- |
| ByVal *x* As String | char **x* |
| ByRef *x* As Byte | unsigned char **x* |
| ByVal *x* As Long | long *x* |

You can still use `Boolean` type for the *fEncrypt* variable in VB6/VBA,
which is equivalent to a 32-bit integer when passed to the core DLL. 
We recommend that you use the defined constants `ENCRYPT` and `DECRYPT` in your VB6 and C code.

### <a id="compilingwithc"></a>Compiling with C

Here is some minimal C code:-

```
/* myprog.c */
#include <stdio.h>
#include "diCrPKI.h"
int main(void)
{
    long version;
    version = PKI_Version(NULL, NULL);
    printf("Version=%ld\n", version);
    return 0;
}

```

To compile with MSVC++:

```

cl myprog.c diCrPKI.lib

```

Running this program should result in something similar to

```

Version=120300

```

where the actual number displayed depends on which version you have installed.

### <a id="borlandc"></a>Using With Borland C++

The lib file distributed with the program is made using MSVC. With Borland you need to generate
a new .lib file directly from the DLL using the IMPLIB utility (note the order of the arguments):

```

implib dicrpki_b.lib diCrPKI.dll

```

To compile with Borland C++:

```

bcc32 mysource.c dicrpki_b.lib

```

### <a id="mingw"></a>Using With MinGW gcc

The newest versions of MinGW gcc will automatically link to .LIB files created by MSVC in most cases.
The .lib file we distribute works for us with MinGW 3.4.5.

To compile with MinGW:

```

gcc PKI_Examples.c diCrPKi.lib -o PKI_Examples

```

### <a id="cautionsforcusers"></a>Cautions for C/C++ Users

* Apply the same rules to these toolkit functions as you would when calling Win32 API functions.
* As a C programmer, you'll be familiar with dimensioning your output variables correctly before 
writing to them or suffering the consequences.
The same rules apply here.
* Remember that output `char` strings require an *extra* char for the NUL terminating
character, so add one more to the size a VBA programmer would use
(see [C/C++ users must add one to this value](#cusersaddone))

    For example

    ```

    char sDigest_sha1[41]; /* SHA-1 digest is 40 hex chars plus NUL */
    char sDigest_sha2[65]; /* SHA-256 digest is 64 hex chars plus NUL */

    ```

    or

    ```

    #include <stdlib.h>
    char *buf;
    buf = malloc(PKI_MAX_HASH_CHARS + 1);  // ADD ONE
    /* ... */
    free(buf);

    ```

We recommend using the defined constants like `PKI_MAX_SHA1_CHARS`
and `PKI_MAX_SHA1_BYTES` rather than hard-coded numbers, e.g.

```

char sDigest_sha1[PKI_MAX_SHA1_CHARS + 1]; 

```

See the constants in `diCrPKI.h`.

### <a id="cusersaddone"></a>C/C++ users must add one to this value...

The VBA examples in this manual use the VBA String() function to pre-dimension a string output buffer,
where `nChars` is number of characters to be written to the output string.

```

Dim strOutput As String          ' VBA string type
strOutput = String(nChars, " ")  ' Len(strOutput) = nChars

```

> **IMPORTANT:** *C/C++ users must add one to this value when allocating memory.*

```

char *szOutput;                 // C string type
// nChars = number of characters required in output string
szOutput = malloc(nChars + 1);  // add one to the number of characters

```

Note that this is only for a C **string** type (`char *szOutput`). 
For **byte** arrays, (`unsigned char *lpOutput`), use the exact number of bytes in your C/C++ code.

```

Dim lpOutput() As Byte      ' VBA byte array type
ReDim lpOutput(nBytes - 1)  ' VBA array of exactly nBytes (0..nBytes-1)

```

```

unsigned char *lpOutput;    // C byte array type
// nBytes = number of bytes required in output byte array
lpOutput = malloc(nBytes);  // exact number of bytes

```

### <a id="examplesccode"></a>Examples of C code

For examples, see the test code `PKI_Examples.c` and `PKICheck.c`
provided in the distribution (these should be in `C:\Program Files (x86)\CryptoSysPKI\C`)
and the examples on our [web page](https://cryptosys.net/pki/pkiexamples.html "External link").

[[Contents](#topofpage)] [[Index](#index)]

<a id="UsingWithCpp"></a>Using with C++ (STL)
---------------------------------------------

The C++ (STL) interface to CryptoSys PKI is an interface to `diCrPKI.dll` for C++ programmers using STL (C++11 or above).

Required files to compile in a C++ project:

```

dipki.hpp
diCrPKI.h
dipki.cpp
   #include "diCrPKI.h"
   #include "dipki.hpp"
{main}.cpp
   #include "dipki.hpp"
   int main() { ... }

```

Link to `diCrPKI.lib`. In MSVC++, with the LIB file in the output directory (typically `Debug` or `Release`)

```

Configuration Properties > Linker > Input > Additional Dependencies: $(OutDir)diCrPKI.lib;%(AdditionalDependencies)

```

A minimal example `dipki-cpp-min.cpp`

```

#include <iostream>
#include "dipki.hpp"
int main()
{
    std::cout << "Gen::Version=" << dipki::Gen::Version() << std::endl;
}

```

Using the command-line with MSVC:

```

CL dipki-cpp-min.cpp dipki.cpp /EHsc /link ..\debug\diCrPKI.lib

```

Using GCC (make sure the DLL has been compiled for target X64):

```

g++ -std=c++11 dipki-cpp-min.cpp dipki.cpp "C:\fullpath\to\x64\Debug\diCrPKI.lib"

```

See the  detailed on-line [programmer's reference](https://cryptosys.net/pki/cpppki/html/index.html "External link").

**Note:** *All* the C++ methods are static and are called directly without creating any object. 

<a id="UsingWithDotNet"></a>Using with .NET: C# and `VB.NET`
------------------------------------------------------------

To use the .NET interface with C# and `VB.NET` (VB2010+):

1. Copy the dotnet `diCrSysPKINet.dll` library file into a convenient folder 
(the install program puts this file by default in 
`C:\Program Files (x86)\CryptoSysPKI\DotNet`).
2. In your application, add a reference to the library:

    1. **Project** > **Add Reference**.
        2. In the .NET tab, click on the **Browse** button to find and select the library file 
        			`diCrSysPKINet.dll`.

        3. Click on **OK** and the wizard will add the reference of the class library to your project.
3. Add the line (for C#)

    ```

    using CryptoSysPKI;

    ```

    or (for `VB.NET`)

    ```

    Imports CryptoSysPKI

    ```

    to your code.

4. Call the methods in the various classes.
Note that the methods in the .NET interface may have different parameters and return values 
to the functions in the core VB6/C DLL.

    * See the [List of .NET Methods](#methodlist) for details of syntax and usage.
        * More complete details are in the supplementary [.NET Help File](#dotnethelp).
        * To find the equivalent .NET method for a VB6 function, see [Cross-reference between Functions and .NET Methods](#xrefdotnet).
        * For a quick guide to converting VB6 code to `VB.NET`, see [Converting VB6 to `VB.NET`](#vb6tovbnet).

Alternatively, with C#, you can just include the source code module `CryptoSysPKI.cs` in your project
and there is no need to reference the class library DLL.

Note that you must also have the core Win32 (or X64) executable `diCrPKI.dll` installed on your system
for the .NET interface to work. If not, it will throw an exception immediately:

> ```
> 
> Unhandled Exception: System.DllNotFoundException: 
> Unable to load DLL 'diCrPKI.dll': 
> The specified module could not be found. 
> (Exception from HRESULT: 0x8007007E)
> 
> ```

If you are working on a 64-bit system, Visual Studio will go looking for the 64-bit core DLL in the Windows system folder 
(usually `C:\Windows\System32`). 
Make sure you set the **Solution Platform** to be **Any CPU**.

The .NET class library `diCrSysPKINet.dll` is compiled for all platforms (Win32 and X64) and 
requires at least .NET 4.0 and should be upwardly compatible with all later .NET versions.
This means that you must be using VS2010 or later.

All methods in the CryptoSysPKI .NET Class Library are static methods. 
You do not need to instantiate or dispose of any objects.

For examples, see the test code `TestPKIcsharp.cs` and `TestPKIvbnet.vb`
provided in the distribution.

The file `diCrSysPKINet.dll` and distribution test code will be found in the DotNet sub-directory of the installation folder, typically
`C:\Program Files (x86)\CryptoSysPKI\DotNet` (or `C:\Program Files\CryptoSysPKI\DotNet` on a 32-bit machine). 

To find the installation folder, use **Start > All Programs > CryptoSysPKI > CryptoSys PKI Reference Files**.

If you need to convert old VB6 code, see [Converting VB6 to `VB.NET`](#vb6tovbnet).

### <a id="bitwiseoptions"></a>Combining bitwise options

To combine bitwise options in .NET, use the bitwise OR operator.

With VB use `Or`

```

X509.OutputOpts.Ldap Or X509.OutputOpts.Latin1

```

With C# use `|`

```

X509.OutputOpts.Ldap | X509.OutputOpts.Latin1

```

[[Contents](#topofpage)] [[Index](#index)]

<a id="UsingWithPython"></a>Using with Python
---------------------------------------------

```

>>> from cryptosyspki import *
>>> Gen.version() # "hello world!" for CryptoSys PKI
200600
>>> Hash.hex_from_data(b'abc') # compute SHA-1 hash in hex of 'abc' as bytes
'a9993e364706816aba3e25717850c26c9cd0d89d'
>>> Hash.hex_from_string('abc', Hash.Alg.SHA256)   # same but over a string and using SHA-256
'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'
>>> h = Hash.data(b'abc')   # h is a byte array (bytes->bytes)
>>> print(Cnv.tohex(h))     # display the byte array in hex
A9993E364706816ABA3E25717850C26C9CD0D89D

```

More details on installation and usage at [A Python interface to CryptoSys PKI Pro](https://cryptosys.net/pki/python.html "External link")
and
[Python CryptoSys PKI Cross Reference](https://cryptosys.net/pki/python-pki-xref.html "External link"). 
To install the interface from PyPi

> ```
> 
> pip install cryptosyspki
> 
> ```

[[Contents](#topofpage)] [[Index](#index)]

<a id="utf8andlatin1"></a>UTF-8 and Latin-1
-------------------------------------------

### Deprecated and obsolete UTF-8 functions

These deprecated UTF-8-related functions are deprecated and should be replaced.
The .NET method `Cnv.CheckUTF8(String)` is obsolete and has been withdrawn in [v11.0].

| Deprecated | Replaced by |
| --- | --- |
| `CNV_UTF8FromLatin1` | [`CNV_UTF8BytesFromLatin1`](#CNV_UTF8BytesFromLatin1) |
| `CNV_Latin1FromUTF8` | [`CNV_Latin1FromUTF8Bytes`](#CNV_Latin1FromUTF8Bytes) |
| `CNV_CheckUTF8` | [`CNV_CheckUTF8Bytes`](#CNV_CheckUTF8Bytes) |
| `Cnv.CheckUTF8(String)` (withdrawn) | [`Cnv.CheckUTF8(Byte[])`](#M_Cnv_CheckUTF8) method |

The change is subtle.
Strictly speaking, the concept of "converting" a string of characters from one character encoding scheme to another is meaningless. 

What we really mean is that we want to change the byte array that
represents the string in Latin-1 encoding to a new byte array that represents the same string using UTF-8 encoding.

The deprecated string-based functions just "forced" the UTF-8-encoded bytes back into a string type.
This forcing trick will work in VB6/C but does not in .NET (well, you can but it's a lot of effort, and pointless).
The resulting "UTF-8 strings" will print "funny" but you could pass them to `HASH_HexFromString`
and obtain the correct hash digest.

*Aside:* 
We had intended to completely remove these three string-based VB6/VBA functions in v11.0 but then discovered we used them ourselves
in an Access VBA application to fix up UTF-8 strings from emails before saving in a database. So, er, they are reprieved.

If you need to "convert" a string to UTF-8 while using this cryptography toolkit,
you probably intend to pass the result to a message digest hash or signature function. 
The underlying hash functions work with byte arrays anyway and so you should really just go directly from the Latin-1 string to 
a byte array containing bytes of the correct UTF-8 encoding. Then you can check you have the correct bytes and can pass this
array directly to the "Bytes" version of the hash function.

We have also added the new function [`CNV_ByteEncoding`](#CNV_ByteEncoding) and equivalent method
[`Cnv.ByteEncoding`](#M_Cnv_ByteEncoding) to convert encoding in a byte array between UTF-8 and Latin-1.
Again, by working with byte arrays, we are doing it the right way.

Both VB6 and .NET store strings internally in "Unicode" encoding (more accurately, UTF-16) 
but when passed to this Toolkit
they are automatically converted to strings of "ANSI" characters. For more information, see
[Converting strings to bytes and vice versa](#stringstobytes)

### Sample code

Here's how to change the code in VBA to obtain the SHA-1 digest of a UTF-8-encoded string using the new functions.

```

Dim strData As String
Dim strDataUTF8 As String
Dim abDataUTF8() As Byte
Dim strDigest As String
Dim nRet As Long
Dim nLen As Long

' Our original string data
strData = "Estándares de Electrónica de México para mañana"
' "Convert" to UTF-8
nLen = CNV_UTF8FromLatin1("", 0, strData)
nLen = CNV_UTF8BytesFromLatin1(0, 0, strData)
If nLen <= 0 Then
    Debug.Print "Failed to convert to UTF-8: " & nLen
    Exit Function
End If
strDataUTF8 = String(nLen, " ")
ReDim abDataUTF8(nLen - 1)
nLen = CNV_UTF8FromLatin1(strDataUTF8, nLen, strData)
nLen = CNV_UTF8BytesFromLatin1(abDataUTF8(0), nLen, strData)

' Create a hash but first dimension the string to receive it
strDigest = String(PKI_SHA1_CHARS, " ")
nRet = HASH_HexFromString(strDigest, Len(strDigest), strDataUTF8, Len(strDataUTF8), PKI_HASH_SHA1)
nRet = HASH_HexFromBytes(strDigest, Len(strDigest), abDataUTF8(0), nLen, PKI_HASH_SHA1)
Debug.Print "Digest=" & strDigest

```

This should result in the output:

```

Digest=3eeb1871c14cd03af6d586850e3058fa80cbbe51

```

The same as above but using much briefer (and safer) VBA wrapper functions.

```

Dim strData As String
Dim strDigest As String
strData = "Estándares de Electrónica de México para mañana"
' Compute SHA-1 hash over UTF-8 encoded bytes in one line
strDigest = hashHexFromBytes(cnvUTF8BytesFromLatin1(strData), PKI_HASH_SHA1)
Debug.Print "Digest=" & strDigest

```

Here is code to do the same thing in `VB.NET`.

```

Dim strData As String
Dim abDataUTF8() As Byte
Dim strDigest As String
' Our original string data
strData = "Estándares de Electrónica de México para mañana"
' "Convert" to UTF-8
abDataUTF8 = System.Text.Encoding.UTF8.GetBytes(strData)
' Compute hash value
strDigest = Hash.HexFromBytes(abDataUTF8, HashAlgorithm.Sha1)
Console.WriteLine("Digest=" & strDigest)

```

And in C#, doing it all in one line.

```

string strData;
string strDigest;
strData = "Estándares de Electrónica de México para mañana";
strDigest = Hash.HexFromBytes(System.Text.Encoding.UTF8.GetBytes(strData), HashAlgorithm.Sha1);
Console.WriteLine("Digest=" + strDigest);

```

[[Contents](#topofpage)] [[Index](#index)]

<a id="filenamesinternational"></a>Filenames with "International" characters
----------------------------------------------------------------------------

All functions in this Toolkit that pass a filename as an argument only support filenames in single-byte "ANSI" encoding.
So ASCII and Latin-1 filenames like `abcdef.txt` and `México.xml` are OK, but a Chinese filename like 
`你好.txt` will fail.

To solve this, use a little-known hack on Windows that retrieves the short path name of a file, `GetShortPathName`. 
This was originally designed to provide an MS-DOS-compatible form of a file path where each folder name and filename is 8 characters or fewer.
So, for example, the long name 

```

C:\Test\Documents and Settings\My Documents\ForEmailWithALongNameLikeThisFolderHas\helloFileWithaLongNameToo.txt

```

reduces to something like

```

C:\Test\DOCUME~1\MYDOCU~1\FOREMA~1\HELLOF~1.TXT

```

where each component of the path name is 8 characters or fewer.

It turns out that this function will provide an ASCII-character equivalent of the name of a file in any Windows "International" UTF-16 characters.
The short name is safe to use with any function in this Toolkit that requires a filename parameter. 

Use the function [`CNV_ShortPathName`](#CNV_ShortPathName) to get a ASCII filename that will work with any function in this Toolkit. Examples:

| System Filename | ShortPathName |
| --- | --- |
| 你好.txt | `FC0F~1.TXT` |
| こんにちは世界.txt | `C001~1.TXT` |
| Приветмир.txt | `E173~1.TXT` |

The exact short path name may be different on your system. 

The file path must exist, though. So if you want to *output* to a file with a name in, say, Japanese or Chinese characters, then you must create a dummy file of the required name, get
its short path name, and then output to a file of that name, which will automatically overwrite the original dummy file.

[[Contents](#topofpage)] [[Index](#index)]

<a id="securityissues"></a>Security Issues
------------------------------------------

1. The functions and methods in CryptoSys PKI Pro provide cryptographic primitives 
intended to be used as part of a security-related application. 
It is up to you the programmer to ensure that keys, passwords and other private data are kept secret,
and to ensure that appropriate security policies and procedures are followed by end users.
2. CryptoSys PKI Pro is a dynamically linked library (DLL) 
that provides cryptographic services to 
applications running on Microsoft Windows® operating systems.
On Windows, it is designed for and supports multi-threaded operation.
3. In FIPS 140-2 terms, CryptoSys PKI Pro is a multi-chip standalone module, 
consisting of the file `diCrPKI.dll`.  It is intended to meet FIPS 140-2 security level 1. 
The cryptographic boundary for CryptoSys PKI Pro 
is defined as the enclosure of the computer on which the cryptographic module is installed. 
As a pure software product, CryptoSys PKI Pro provides no physical security by itself. 
The computer itself must be appropriately physically secured.
4. Functions that advertise they create an output file will overwrite
any existing file of the same name without warning.
5. No other files, temporary or permanent, are *ever* created by the toolkit ([exception](#tempfileexception)).
6. There is no communications functionality whatsoever in the toolkit DLL. 
The toolkit will never attempt to "dial home" or make any attempt to create a communications socket.
If your firewall tells you there is an attempt
to create an internet connection, you have a virus or trojan of some sort unrelated to the
CryptoSys PKI Pro toolkit.
7. The Developer version of the toolkit makes no attempts to read or write to the Windows registry whatsoever
under normal operations. 
However, [optional registry settings](#registrysettings) may be made
and, if they exist, will be read and acted on by the module if a [critical error](#criticalerrors) occurs.
8. The Trial version creates and updates registry entries in `HKCU\Software\DI Management`
and reads entries created by the setup utility in `HKLM\Software\DI Management`. 
Do not attempt to change these entries.
9. Developer versions distributed to end users do *not* require any registry entries on the user's machine
(but see [optional registry settings](#registrysettings)).
10. To check you have a valid version of the CryptoSys PKI Pro executable, please check the
integrity checksums published on our [web site](https://cryptosys.net/pki/pkiintegrity.html "External link").
11. It is your responsibility to protect unencrypted private keys and password strings.
12. Some functions require the input to be provided as a file or create a file of the output. 
It is your responsibility to clean up these files after use.
13. VB6/C functions that write output to a string require the string to be "pre-dimensioned" first. All such
functions require the length to be specified. Make sure the specified length matches the size of the string or a
GPF error will result.
14. Except for the `X509_CertIsValidNow` and `X509_ValidatePath` functions, no checks are made on
the validity period of X.509 certificates by any other functions in this toolkit, nor are the key usage flags checked. 
Any correctly-formatted X.509 certificate is considered valid for any purpose.
It's up to you to make your own checks before use.
15. Read the section on [Key Security](#keysecurity) below.

<a id="tempfileexception"></a>**Temporary file exception:** *[New in v12.0]* The  function [`ASN1_TextDumpToString`](#ASN1_TextDumpToString) 
	and method [`Asn1.TextDumpToString`](#M_Asn1_TextDumpToString) create a locked temporary file which is automatically deleted.

[[Contents](#topofpage)] [[Index](#index)]

<a id="keysecurity"></a>Key Security
------------------------------------

The primitives in this toolkit allow you to do a lot of low-level operations with RSA and ECC keys.
The original design only permitted private keys to be stored as a file in encrypted format.
In response to many requests from users, we've added various functions that allow you to import and
save private keys in a variety of unencrypted formats, including XML and OpenSSL-compatible PEM formats.

Use these functions in your tests by all means, but if you are using this toolkit to make an application
to be used by less-experienced end users (and this is almost always the case), follow the following guidelines:

* Do not give your users the ability to save an unencrypted private key, ever. Just say no.
* Never, ever save production private keys to disk in unencrypted format. 
Remember that's *never*, even when testing (*especially* when testing).
* Use the [`WIPE_Data`](#WIPE_Data) function to wipe the 
internal private key string as soon as you've finished using it.
* Ditto for passwords.
* If you have to save secret data as an intermediate file, 
use the [`WIPE_File`](#WIPE_File) function to erase it immediately afterwards.
Make sure this happens even if an error condition occurs.
* Never print out the "internal" string representation of a production private key. 
(We know we do in our examples, but that's to demonstrate how it works.) 
Likewise the password. See [Internal key strings](#internalkeys).
* Do not hard code private key strings or passwords, ever. (Again, do as we say, not as 
we do in our examples.) See [Internal key strings](#internalkeys).
* If you need a private key on a server to be used repeatedly in internal format,
force the administrator to enter the password each time the server starts.
Set up a hierarchy of keys and certificates in case the server key gets compromised.
* Enforce a policy so that users are forced to use strong passwords for the private key.
The higher up the chain the longer the password needs to be.
Do not compromise on this, even when the client complains.
It's good practice for important passwords to be so long that they have to written down.
Keep the piece of paper in a safe.
* And build in a function that detects when the user has stuck a Post-It note 
on their monitor with the private key password on it.

<a id="internalkeys"></a>Internal key strings
---------------------------------------------

This toolkit uses what we call an ***internal key string*** to hold a locally-encrypted copy of RSA and ECC keys.
This key string is *ephemeral* in the sense it is only short lived. It expires at the end of your current session.

The principle is that you read in the key from a file as a one-off operation using its password into an "internal key string"
and you can then use this string for other operations that require the key without requiring your important password again.

When your current session finishes (i.e. when the process ends), the internal key string is of no use. 
If it is accidentally printed or saved, it cannot be used to compromise your real key.

This means

* You cannot hardcode the internal key strings to re-use at a later date
* You cannot share an internal key string between different processes
* You cannot rely on getting the same string when re-reading a key from a file, even in the same process. 
If you need to compare internal RSA key strings, use the 
[`RSA_KeyHashCode`](#RSA_KeyHashCode) function.

You should always read in the key data from the private and public key files, PFX files, or X.509 certificates
at the time they are required. 
An internal key string is a string of base64 characters but please treat it as an opaque "blob". 
Its structure may change without notice in a future revision.

[[Contents](#topofpage)] [[Index](#index)]

<a id="encryptedkeyoptions"></a>Security options for encrypted private keys
---------------------------------------------------------------------------

Private keys are created and saved by default in a PKCS#8 encrypted format, protected by a password. 
The default algorithm is `"pbeWithSHAAnd3-KeyTripleDES-CBC"` from PKCS#12.

To increase security use one of the  stronger 
PBES2 encryption schemes from PKCS#5 v2 using the key derivation function PBKDF2:

1. `PKI_PBE_PBKDF2_DESEDE3` for PBKDF2 using `des-EDE3-CBC`
2. `PKI_PBE_PBKDF2_AES128` for PBKDF2 using `aes128-CBC`
3. `PKI_PBE_PBKDF2_AES192` for PBKDF2 using `aes192-CBC`
4. `PKI_PBE_PBKDF2_AES256` for PBKDF2 using `aes256-CBC`

*[Changed in v11.0]* The above option values are a simplified alternative to
`PKI_PBE_PBES2+PKI_BC_AES128`, etc.

The default pseudorandom function (PRF) for PBKDF2 is `hmacWithSHA1`.
To use a stronger HMAC function from the SHA-2 family in the PRF for PBKDF2, add one of the following options

1. `PKI_HMAC_SHA224` for `hmacWithSHA224`
2. `PKI_HMAC_SHA256` for `hmacWithSHA256`
3. `PKI_HMAC_SHA384` for `hmacWithSHA384`
4. `PKI_HMAC_SHA512` for `hmacWithSHA512`

For legacy applications, you can still use the old, less secure, PBES1 schemes using DES from PKCS#5 v1.5.
These are *definitely* not recommended for new applications. Not available for ECC private keys.

*[Changed in v11.0]* note that the values for these flags have changed. 

* `PKI_PBE_MD5_DES` for `pbeWithMD5AndDES-CBC` (legacy, not recommended)
* `PKI_PBE_MD2_DES` for `pbeWithMD2AndDES-CBC` (legacy, not recommended)
* `PKI_PBE_SHA_DES` for `pbeWithSHA1AndDES-CBC` (legacy, not recommended)

Remember that the security of all these schemes is limited by the strength of the password used.
Other applications may not support all the alternatives provided here.

[[Contents](#topofpage)] [[Index](#index)]

<a id="eccrypto"></a>Elliptic Curve Cryptography (ECC)
------------------------------------------------------

You can use the elliptic curve cryptography functions in this toolkit to sign data using the ECDSA and EdDSA algorithms
(see [`SIG_SignData`](#SIG_SignData) and [`SIG_SignFile`](#SIG_SignFile) and
the [`Sig class`](#mx_Sig) methods). 
*[New in v20.0]* You can also perform elliptic curve Diffie-Hellman key exchange (ECDH) - see [`ECC_DHSharedSecret`](#ECC_DHSharedSecret).

You can create your own elliptic curve keys, and read, analyze and save keys in the standard key file formats,
both encrypted and unencrypted. 
You can read a key file into an [internal key string](#internalkeys) which is stored in encrypted form valid only for the current session.
We support the following curves over prime fields:

* `P-192`, also known as `secp192r1` and `prime192v1`
* `P-256`, also known as `secp256r1` and `prime256v1`
* `P-224`, also known as `secp224r1`
* `P-384`, also known as `secp384r1`
* `P-521`, also known as `secp521r1`
* `secp256k1` (the Bitcoin curve)
* `Ed25519` (EdDSA only) *[New in v20.0]*
* `X25519` (ECDH only) *[New in v20.0]*
* `Ed448` (EdDSA only) *[New in v22.0]*
* `X448` (ECDH only) *[New in v22.0]*
* `brainpoolP256r1` *[New in v20.4]*
* `brainpoolP384r1` *[New in v20.4]*
* `brainpoolP512r1` *[New in v20.4]*

### Creating a new ECC key pair

To create a new elliptic curve key pair, use the [`ECC_MakeKeys`](#ECC_MakeKeys) function.
This creates two new files, an encrypted private key file and a public key file. 
You can use the ReadKey and SaveKey functions to read in and save these in different formats.

### Key file format

In this toolkit, EC public key files are always stored as DER-encoded `SubjectPublicKeyInfo` types [[RFC5480](#RFC5480)].
In a PEM-encoded file, this should begin with `-----BEGIN PUBLIC KEY`.

The three supported types (all DER-encoded) for an EC private key file are:

1. PKCS#8 `EncryptedPrivateKeyInfo` [[RFC5208](#RFC5208)] encrypted with a password.
This is the (only) output when using [`ECC_MakeKeys`](#ECC_MakeKeys) and [`ECC_SaveEncKey`](#ECC_SaveEncKey).
In a PEM-encoded file, this should begin with `-----BEGIN ENCRYPTED PRIVATE KEY`.
2. `ECPrivateKey` [[RFC5915](#RFC5915)].
This is the default output for a private key using [`ECC_SaveKey`](#ECC_SaveKey).
In a PEM-encoded file, this should begin with `-----BEGIN EC PRIVATE KEY`.
3. Unencrypted  PKCS#8 `PrivateKeyInfo` [[RFC5208](#RFC5208)] 
	(more recently renamed as `OneAsymmetricKey` [[RFC5958](#RFC5958)]
	but identical in structure in this case).
This is an optional output for a private key using [`ECC_SaveKey`](#ECC_SaveKey) with the `PKI_KEY_TYPE_PKCS8` option.
In a PEM-encoded file, this should begin with `-----BEGIN PRIVATE KEY`.

Key files can be saved as binary (default) or PEM-encoded (with the `PKI_KEY_FORMAT_PEM` option).
These encodings are detected automatically when reading a key file.

Use the [`ECC_ReadKeyByCurve`](#ECC_ReadKeyByCurve) function to read in a key in a 
[hex format](#ecchexformat) string,
then you can save it as a file in a supported key format.
If your key is in base58 encoding, use [`CNV_Base58ToBytes`](#CNV_Base58ToBytes) to decode, then
[`CNV_HexStrFromBytes`](#CNV_HexStrFromBytes) to obtain the hex form string
(in .NET just use `Cnv.ToHex(Cnv.FromBase58(b58str))`).

To change the format of an EC key file, read the file into an "internal" string using 
[`ECC_ReadPrivateKey`](#ECC_ReadPrivateKey) or
[`ECC_ReadPublicKey`](#ECC_ReadPublicKey),
then save it as a file again using 
[`ECC_SaveKey`](#ECC_SaveKey) or
[`ECC_SaveEncKey`](#ECC_SaveEncKey).
To obtain the public key from a private key, read the private key into an internal string and then use
[`ECC_PublicKeyFromPrivate`](#ECC_PublicKeyFromPrivate).
To analyze an EC key file, read it into an internal string and use
[`ECC_QueryKey`](#ECC_QueryKey).

### <a id="ecchexformat"></a>Hex format for NIST/SEC EC keys

Private key in hex

:   An EC private key `w` is represented in hex by the hexadecimal encoding of its integer value encoded in octets as per section 3 of 
[[RFC5915](#RFC5915)], denoted here as `HEX(w)`.

Public key in hex

:   An EC public key `(x,y)` is represented in hex by the hexadecimal encoding of the octet string as defined in section 4.3.6 of 
[[X9-63](#X9-63)]:

> `04||HEX(x)||HEX(y)`

Compressed representation (beginning "02" or "03") is [not supported](#compressedkey) due to patent issues.

Note that the format is different for the [safe curves](#eccsafecurves) X25519, Ed25519, X448 and Ed448.

### Format of ECDSA signature

An ECDSA signature consists of a pair of integers `(r,s)`.
There are two representations of ECDSA signatures used in this toolkit:

1. A simple concatenation of two octet strings resulting from the integer-to-octet encoding of the values of 
	`r` and `s`, in that order (i.e. `r||s`) 
	as specified in section 6.4.1 of [[XMLDSIG](#XMLDSIG)] 
	with a length parameter *l* equal to `ceiling(log2(q)/8)` where `q` is the order of the curve.

    This is the default output in this toolkit. 
    It is the form expected for a `SignatureValue` in an XML-DSIG signature [[RFC4050](#RFC4050)] 
    and is described in section E3.1 of [[IEEE1363](#IEEE1363)].
2. The DER-encoded ASN.1 structure
of the signature (a SEQUENCE of two INTEGERs for `r` and `s`, in that order).
This is the representation used by Bitcoin and in X.509 certificates and is an optional output in this toolkit.
Use the `PKI_SIG_ASN1DER` option flag.

By default, these representations are formatted in base64 encoding.
Use the `PKI_ENCODE_BASE64URL` option to format the signature in [URL-safe "base64url"](#base64url) encoding,
or the `PKI_ENCODE_HEX` option for hexadecimal (base16) encoding.

### Do you support X.509 certificates containing or signed with elliptic curve keys?

Yes, as of *[v12.0]* we do. See, for example, [`X509_MakeCert`](#X509_MakeCert) and [`ECC_ReadPublicKey`](#ECC_ReadPublicKey).

### <a id="compressedkey"></a>Can you read a key in compressed representation?

Definitely not! Due to patent issues, attempts to pass a public key in so-called "compressed representation"
will result in a large Canadian Ogopogo monster from a swamp near Waterloo, Ontario, materialising from your computer and devouring you in a frenzy of blood and gore.
Of course, you are welcome to try and see what happens.

[[Contents](#topofpage)] [[Index](#index)]

<a id="eccsafecurves"></a>Safe curves for elliptic cryptography
---------------------------------------------------------------

*[New in v20.0]* The elliptic "safe curve" algorithms
  X25519 and Ed25519 are now supported in this Toolkit
  and *[New in v22.0]* so are X448 and Ed448.

X25519 and X448 are key agreement algorithms based on the Montgomery curves
  "curve25519" [[CURVE25519](#CURVE25519)] and "curve448" (also known as "goldilocks") 
  [[GOLDILOCKS](#GOLDILOCKS)].
  
  The use of X25519 and X448 for Elliptic Curve Diffie-Hellman key exchange
  (ECDH) is described in [[RFC7748](#RFC7748)].
  

Ed25519 and Ed448 are elliptic curve signature schemes Edwards-curve
  Digital Signature Algorithm (EdDSA) described in [[RFC8032](#RFC8032)].
  Ed25519 uses the twisted Edwards curve "edwards25519", which is
  birationally equivalent to curve25519 [[ED25519](#ED25519)].
  

curve25519, edwards25519 and curve448 are "safe curves" [[SAFECURVES](#SAFECURVES)]. 
These have many security advantages over the standard NIST/SEC curves.

In this documentation we refer to these algorithm/curve
  combinations as **"safe curves"** to differentiate
  them from the NIST/SEC elliptic curves such as `secp256r1`.
  There are many differences in the use of these two classes of
  elliptic curves, noted below.

The terms "X25519" and "Ed25519" are used to describe the
  algorithm/curve combination.
  The convention is that "X25519" is used when curve25519 is
  used with the Diffie-Hellman operation,
  and "Ed25519" when used for the EdDSA signature operation in
  PureEdDSA mode [[RFC8410](#RFC8410)]
  (similarly for "X448" and "Ed448").

The curve25519 algorithm/curve combinations are designed to operate at
  about the 128-bit security level equivalent to NIST P-256 or
  AES-128, and the curve448 combinations at around the 224-bit security level.

### Features of X25519 and Ed25519

* The private and public keys for both X25519 and Ed25519 are all represented by a 32-byte string.
* X25519 allows all 32-byte strings as public keys.
* Ed25519 allows all 32-byte strings as private keys.
* Ed25519 signatures are always 64 bytes long, with the three
  most significant bits of the final byte always zero.
* The public keys for X25519 and Ed25519 are derived from the
  secret key in different ways and cannot be interchanged.

### Features of X448 and Ed448

* The private and public keys for X448 are represented by a 56-byte string,
and the private and public keys for Ed448 are represented by a **57**-byte string.
* Ed448 signatures are always 114 bytes long.
* The public keys for X448 and Ed448 are derived from the
secret key in different ways and cannot be interchanged (and anyway are different lengths).

### Masking/clamping for X25519 and X448 private keys

* There are masking (clamping) requirements for X25519 and X448 private keys 
- see Section 5 of [[RFC7748](#RFC7748)] - but these seem to be ignored in published test vectors,
as we do here.

    This Toolkit will accept **any 32-byte string** as an
    X25519 private key and **any 56-byte string** as an X448 private key.
    Any required masking will be applied before the key is used.

### Some differences from the NIST/SEC curves

* The NIST/SEC elliptic curves can be used for both ECDH key
	  exchange and ECDSA signatures, but Ed25519/Ed448 cannot be used for
	  key exchange and X25519/X448 cannot be used for signatures.
* For NIST/SEC curves, the difference between a private key and
	  public key is obvious from its structure. This is not the case
	  for safe curves where the private and public keys are the same
	  length.
* When using the [`ECC_ReadKeyByCurve`](#ECC_ReadKeyByCurve) function with
	  safe curves, the user must explicitly specify whether the key
	  is a private key or public key.
* The hexadecimal encoding of safe curve keys is different from
	  that used for NIST/SEC keys. Safe curve keys are encoded using
	  the little-endian convention,
	  whereas NIST/SEC curves are encoded using the big-endian
	  convention as per [[RFC5915](#RFC5915)] using the I2OSP primitive defined
	  in [[RFC3447](#RFC3447)].
	  The encoding for safe curves used in this Toolkit is
	  consistent with that used in the reference documents
	  (other implementations may differ).
* When using the ECDSA signature algorithm with the NIST/SEC
	  curves, you can pass the hash digest of the message to the
	  signature function to create the signature as an alternative
	  to passing the entire message.
	  However, Ed25519 and Ed448 cannot create or verify a signature using the
	  hash of the message. The full message *must* be passed
	  to the sign or verify function.
	  To sign or verify a file with Ed25519/Ed448, you must read in all the data first
	  and pass that directly to the [`SIG_SignData`](#SIG_SignData)
	  function.

[[Contents](#topofpage)] [[Index](#index)]

<a id="technicaldetails"></a>Technical Details
----------------------------------------------

The core executable **`diCrPKI.dll`** is a native Windows **DLL** compiled using 
Microsoft Visual C++ for both Win32 (x86) and X64 platforms (there are separate DLL files for each platform).
This type of file used to be called a **Win32 DLL**.
All programming language interfaces require this core native DLL to exist in the library search path of the user's system.
The core cryptographic functions are written in pure ANSI C with extensive internal checks for memory leaks and overflow issues.
The executable `diCrPKI.dll` is compatible with *all* versions of Windows XP and above.
It does not require any other special libraries to work apart from the standard Win32 libraries available in *all*
modern versions of Windows. 
It is totally independent of the Microsoft Cryptographic API.

The wrapper executable **`diCrSysPKINet.dll`** is a **.NET Class Library** 
created with Microsoft Visual C# set to target Microsoft .NET Framework 4.0 and above. 
It is compiled for all target platforms: Win32 and X64. 
This requires at least .NET 4.0 and should be upwardly compatible with all later .NET versions.
It can be called from programs written in C# and `VB.NET` (aka VB2010+). 
The .NET class library calls the functions in the core native DLL using `System.Runtime.InteropServices`.
The source code for this wrapper DLL is provided in the distribution, which you can use directly in your C# projects instead of referencing the .NET DLL.
For more details on its use, see [Using with .NET](#UsingWithDotNet).

[[Contents](#topofpage)] [[Index](#index)]

<a id="selftests"></a>Self-Tests
--------------------------------

The module performs power-up self-tests and conditional self-tests to ensure that it is functioning properly.
[Power-up self-tests](#powerupselftests) are performed when the module is powered up, i.e. when the DLL is first attached to the 
parent Windows process. 
[Conditional self-tests](#conditionaltests) are performed when certain security functions are invoked.

### <a id="powerupselftests"></a>Power-up Self-Tests

The following power-up self-tests are performed:-

* [Cryptographic algorithm test](#cryptoalgtest)
* [RNG health test](#rnghealthtest)
* [Software integrity test](#softwareintegritytest)

#### <a id="cryptoalgtest"></a>Cryptographic algorithm test:

* Triple DES known-answer test
* AES known-answer tests for AES-128/192/256
* Message digest known-answer tests for MD5, SHA-1, SHA-2 and SHA-3
* HMAC known-answer tests for MD5, SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512
* RSA public and private key pair-wise consistency test using a known key pair

#### <a id="rnghealthtest"></a>RNG health test:

The random number generator implementation performs the following self-tests to obtain assurance 
that the Deterministic Random Bit Generator (DRBG)
continues to operate as designed and implemented (as per section 11.3, [[SP80090A](#SP80090A)]).

* Known-answer test on the DRBG mechanism
* Known-answer test on the instantiate function
* Known-answer test on the generate function
* Known-answer test of the reseed function
* Test of the uninstantiate function

#### <a id="softwareintegritytest"></a>Software integrity test:

The integrity of the software module is tested using a 32-bit error detection code (EDC). The value of this
EDC is set and stored when the module is created. 
On testing, the EDC is re-computed for the DLL module file being used and compared
with the stored value. If the values do not match, the test fails.

In addition to this automatic software integrity test, the integrity of the entire DLL file can be
independently verified by the user using published message digest and checksum values
before and after installation - 
see [CryptoSys PKI Pro Toolkit Integrity Checks](https://cryptosys.net/pki/pkiintegrity.html "External link").

### <a id="conditionaltests"></a>Conditional Tests

The following conditional tests are performed:-

* [Pair-wise consistency test](#pairwiseconsistencytest)
* [Continuous random number generator test](#rngtest)

#### <a id="pairwiseconsistencytest"></a>Pair-wise consistency test:

When the module generates a public and private key pair, it carries out pair-wise consistency tests for
both encryption and digital signing. The test involves encrypting a randomly-generated message with the public
key. If the output is equal to the input message, the test fails. The encrypted message is then decrypted using
the private key and if the output is not equal to the original message, the test fails. 
The same random message
is then signed using the private key and then verified with the public key. If the verification fails, the test fails.

#### <a id="rngtest"></a>Continuous random number generator test:

When the module is first loaded or instantiated in a new thread, the RNG generates a 64-bit block which is
not used but is saved in thread-safe memory for comparison with
the next 64-bit block to be generated. Each subsequent generation of a 64-bit block is
compared with the previously generated block. The test fails if any two compared 64-bit
blocks are equal.
No blocks are saved that have actually been previously output by the generator.

### <a id="selftestfails"></a>Action if a self-test fails

Any failure of a power-up test or conditional test will cause the following actions to take place:

1. An error message will be logged to the event log (NT+ systems only).
2. The system will (try to) save the error message in a log file* in the same directory as the calling process
executable.
3. A message box will display on the screen.
4. The DLL will terminate its own process** to prevent further use of cryptographic functions.

Note that you should never, ever see such a failure unless someone has interfered with the DLL file
or some serious problem has occurred on your system.

* The error log file will be given a filename "pkierr.log". If the
process does not have permissions to write to that directory, no log file be created.

** By terminate its own process, we mean that the CryptoSys DllMain function will return false.
This will cause statically-linked applications to terminate,
and applications that use LoadLibrary, like Visual Basic, 
to return an error message saying it cannot find the DLL file.

You can make settings in the machine's registry to prevent the message box displaying and to change the
destination directory of the log file. See [Optional Registry Settings](#registrysettings).
It is not possible to prevent the DLL from exiting if a [critical error](#criticalerrors) happens.

The user may call the power-up self-tests on demand with the [`PKI_PowerUpTests`](#PKI_PowerUpTests)
function. In the event that such an "on demand" test fails, the module will log the error event and return an error
code but will not terminate the process.

Be aware that the automatic self-tests fail only in exceptional circumstances. You should never see one
in practice unless the software module has been tampered with. 

[[Contents](#topofpage)] [[Index](#index)]

<a id="criticalerrors"></a>Critical Errors
------------------------------------------

A *Critical Error* occurs if and only if one of the following events occur:

* The [Software Integrity Test](#softwareintegritytest) failed on start-up - this means someone has interfered with the DLL file.
* A [Cryptographic Algorithm Test](#cryptoalgtest) failed on start-up - for some reason one of the cryptographic algorithms has failed a 
known-answer test. In theory, this shouldn't happen, but we protect against the unexpected.
* A [Pair-wise Consistency Test](#pairwiseconsistencytest) failed - a freshly-generated public/private key pair is invalid.
* The [Continuous Random Number Generator Test](#rngtest) failed - suspect enemy action!

You should never see a critical error
in practice unless the software module has been tampered with.

[[Contents](#topofpage)] [[Index](#index)]

<a id="registrysettings"></a>Optional Registry Settings
-------------------------------------------------------

The following optional registry settings may be made to change the behaviour of the module if a [critical error](#criticalerrors)
occurs.

### 

> **Disclaimer** Modifying the registry can cause serious problems that may require 
> you to reinstall your operating system. 
> We cannot guarantee that problems resulting from the incorrect use of the registry can be solved. 
> Use the information provided at your own risk.

#### Disable message boxes if a critical error occurs

The default behaviour is to display a pop-up MessageBox if a [critical error](#criticalerrors) occurs. 
Users running the toolkit on an unattended server or within an IIS application can disable pop-ups to prevent
problems (IIS gets a bit upset if an application displays a pop-up).
Set the value to '1' to disable pop-up messages from appearing.
Note that this will not prevent the 'first user' or expiry dialogs appearing with the Test Version.

**Key:** `[HKEY_LOCAL_MACHINE\Software\DI Management\CryptoSysPKI\Options]`  

**Value Name:** `NoMessageBox`  

**Data Type:** REG_DWORD  

**Data:** 1 = MessageBoxes disabled, 0 = MessageBoxes enabled (default)

#### Set directory to write error log file after a critical error

The default behaviour if a [critical error](#criticalerrors) occurs is to try to write to an error log file in the same directory 
as the parent executable file that called the DLL. To change this directory create a REG_SZ value
of 'ErrorLogDir' in the key below and set the value to the directory you want, e.g. "C:\myfolder\subdir". 
The directory name should not have a trailing slash character.

**Key:** `[HKEY_LOCAL_MACHINE\Software\DI Management\CryptoSysPKI\Options]`  

**Value Name:** `ErrorLogDir`  

**Data Type:** REG_SZ

#### Disable creation of error log file if a critical error occurs

To disable the creation of an error log file altogether, create
 a REG_DWORD value of 'NoErrorLog' in the key below. Set the value to '1' to disable.

**Key:** `[HKEY_LOCAL_MACHINE\Software\DI Management\CryptoSysPKI\Options]`  

**Value Name:** `NoErrorLog`  

**Data Type:** REG_DWORD  

**Data:** 1 = Error log file disabled, 0 = Error log file enabled (default)

#### Record event log messages properly

The following registry entry is required for the Event Log messages to be recorded properly.
If this entry is not present, or the path to the DLL is wrong, the event log entries will be
of the form:

> The description for Event ID ( 8xxx ) in Source ( diCrPKI ) cannot be found. 
> The local computer may not have the necessary registry information or message 
> DLL files to display messages from a remote computer.

For correct formatting of the message, create the REG_SZ and REG_DWORD values in the key below.
The message will still be recorded even if this entry is not present.

**Key:** `[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\diCrPKI]`  

**Value Name:** `EventMessageFile`  

**Data Type:** REG_SZ  

**Data:** Full path to DLL file, e.g. "C:\WINNT\system32\diCrPKI.dll"  

   

**Value Name:** `TypesSupported`  

**Data Type:** REG_DWORD  

**Data:** 7 (0x7)

Note that event log messages are only written in exceptional circumstances. You should never see one
in practice unless the software module has been tampered with. 

[[Contents](#topofpage)] [[Index](#index)]

<a id="rnginfo"></a>Random Number Generator
-------------------------------------------

* [RNG Mechanisms](#rngmechanisms)
* [Techniques to add known security strength to the RNG process](#rngtechniques)
* [User-supplied entropy (seeds)](#rngentropy)

### <a id="rngmechanisms"></a>RNG Mechanisms

The random number generator used in the 
CryptoSys PKI Pro toolkit
is designed to conform to
NIST Special Publication 800-90A
*Recommendation for Random Number Generation Using Deterministic Random Bit Generators* 
[[SP80090A](#SP80090A)].
Entropy is accumulated in "Fortuna" pools as described in
Ferguson and Schneier, *Practical Cryptography*, [[FERG03](#FERG03)].

The full technical details are published on our [web site](https://cryptosys.net/rng_algorithms.html "External link"). 

The underlying RNG functions use the algorithms recommended in NIST SP 800-90A 
[[SP80090A](#SP80090A)] (the "DRBG Standard")
to provide a Deterministic Random Bit Generator (DRBG).
The HMAC_DRBG mechanism is used with SHA-512 as the underlying hash function *[Updated in v22.1]*.
This outputs a sequence of binary bits that appears to be
statistically independent and unbiased. The output is effectively random so long
as internal actions of the process are hidden from observation. In particular
the algorithm provides good Backtracking Resistance and, depending how it is
used, good Prediction Resistance.

Entropy is accumulated at startup and whenever any function in the library is called.
Only inobtrusive methods of collecting entropy are used, so you can use the Toolkit safely
in any application.
The "Fortuna" method of pooling is used to prevent certain attacks from someone who
controls some but not all of the entropy sources 
(see chapter 10 of [[FERG03](#FERG03)]). 
The more times your
application calls the functions in the library before needing some random data,
the more entropy will be accumulated. 
The user cannot control how or when the Fortuna entropy is added to the RNG process - this is by design.

The advantage of the Fortuna system is that the level of entropy does not need to be measured. 
There is, however, a period of vulnerability just after start up when there may not be sufficient entropy in the
pools. This can be overcome by initializing with a [seed file](#rngtechniques), or *[New in v22.1]* getting entropy seeds from the Intel(R) DRNG hardware-generated random values,
if supported on your machine.

We strongly recommend that you use and initialize with a seed file wherever possible.

### <a id="inteldrng"></a>Intel(R) DRNG support

*[New in v22.1]*

The Digital Random Number Generator (DRNG) is an innovative hardware approach to high-quality, high-performance entropy and random number generation. 
It is composed of the new Intel 64 Architecture instructions RDRAND and RDSEED and an underlying DRNG hardware implementation.
For more information see [[INTEL-DRNG](#INTEL-DRNG)].

If available on your system, 256 bits of entropy from Intel(R) DRNG (using hardware-generated random values)
will be added automatically on first use of any RNG function. 
The output is used to seed and add entropy to the generator state and Fortuna accumulation pools. It is not used directly.

The availability of support can be checked using the [`RNG_Initialize`](#RNG_Initialize) function and passing an empty `""` filename parameter.
If the return value is a positive number then Intel(R) DRNG is supported (1=RDRAND available, 2=RDSEED available, 3=both RDRAND and RDSEED available).
RDSEED will be preferred if available.
Support can also be explicitly turned off using the `PKI_RNG_NO_INTEL_DRNG` option.

### <a id="rngtechniques"></a>Techniques to add known security strength to the RNG process

1. Use the Intel(R) DRNG hardware-generated source of random seeds

:   If available on your system, calling the Intel(R) DRNG functions retrieves a hardware-generated random seed value which is added to our SP800-90A-compliant DRGB.
This is carried out automatically whenever any RNG function is called from our Toolkit. 
Even if an attacker can monitor the output from the Intel(R) DRNG  calls, they cannot predict the output from our RNG functions.
If not available, then it is ignored.

2. Use a seed file

:   Using a seedfile restores the entropy created during an earlier session and avoids any issues at startup of insufficient entropy in the pools.
Use the 
[`RNG_Initialize`](#RNG_Initialize)
function to specify a seedfile with a known minimum amount of entropy
to initialise the PRNG. This seed file is updated automatically when used. You
should call the 
[`RNG_UpdateSeedFile`](#RNG_UpdateSeedFile)
from time to time in your
application to save any existing entropy, and use 
[`RNG_MakeSeedFile`](#RNG_MakeSeedFile)
to create a new one. 
The security of this
method is as good as the security you have over the seed file. If an attacker
controls the seed file, it does not mean they control the random output data; it
just means that using a seedfile does not increase the security strength of the PRNG.

3. Make the user enter random keystrokes

:   Use the 
[`RNG_BytesWithPrompt`](#RNG_BytesWithPrompt) function 
when generating random data to force the user to
generate entropy using random keystrokes and mouse movements.
[`RNG_MakeSeedFile`](#RNG_MakeSeedFile)
 also uses such a prompt. 
This works provided you know the user's keyboard strokes and mouse movements are secure 
(e.g. are not being transmitted over a network).

4. Add your own entropy

:   If you have your own independent source of entropy (perhaps by monitoring the output of a radioactive isotope :-), add this "additional input"
to the RNG process as a "seed" when using the 
[`RNG_Bytes`](#RNG_Bytes) function.
If you assume zero security strength for the
internally-generated entropy and you add input with, say, 128 bits of security
strength, then the output from the RNG will have at least 128 bits of security
strength.

### <a id="rngentropy"></a>User-supplied entropy (seeds)

User-supplied entropy (a.k.a. a "seed") is added as "additional input" to the generation process.
It does not affect the accumulation pools and cannot be used
by an attacker to control the output.

Remember it's not how "random" your user-supplied entropy is, but how little an
attacker knows about it. Using the current time is no use. If you can provide
32 bytes* of data of which an attacker knows nothing and cannot later discover,
then you have added 128 bits of security strength. 
  
* The bytes must have been selected randomly from the range 0 to 255.

Here is an example in VB6 of how you could use the RNG to generate user-supplied entropy when
creating a new pair of RSA keys. (The password should be entered separately, not hard-coded like this!)

```

Dim nRet As Long
Dim nBits As Long
Dim strPublicKeyFile As String
Dim strPrivateKeyFile As String
Dim strPassword As String
Dim strSeed As String

nBits = 512
strPublicKeyFile = "mykeypub.bin"
strPrivateKeyFile = "mykeypri.bin"
strPassword = "password"

' 1. Generate some user-derived entropy using the keyboard
strSeed = String(64, " ")
nRet = RNG_StringWithPrompt(strSeed, Len(strSeed), "", 0)

' 2. Create a new pair of RSA key files, adding this seed to the process
Debug.Print "About to create a new RSA key pair..."
nRet = RSA_MakeKeys(strPublicKeyFile, strPrivateKeyFile, nBits, _
    PKI_RSAEXP_EQ_65537, 50, 1000, strPassword, strSeed, Len(strSeed), 0)
Debug.Print "RSA_MakeKeys returns " & nRet & " (expected 0)"

' 3. Immediately wipe the sensitive data
Call WIPE_String(strSeed, Len(strSeed))
Call WIPE_String(strPassword, Len(strPassword))

```

And the same example in C# (`VB.NET` is very similar)

```

int r;
byte[] seed;
int nbits = 512;
string publicKeyFile = @"mykeypub.bin";
string privateKeyFile = @"mykeypri.bin";
StringBuilder sbPassword = new StringBuilder("password");

// 1. Generate some user-derived entropy using the keyboard
seed = Rng.BytesWithPrompt(64,"",Rng.Strength.Default);
Debug.Assert(seed.Length > 0, "Failed to create a seed");

// 2. Create a new pair of RSA key files, adding this seed to the process
r = Rsa.MakeKeys(publicKeyFile, privateKeyFile, nbits, 
	Rsa.PublicExponent.Exp_EQ_65537, 1000, sbPassword.ToString(),
	Rsa.PbeOptions.Default, false, seed);
Console.WriteLine("Rsa.MakeKeys returns {0} (expected 0)", r);

// 3. Immediately wipe the sensitive data
Wipe.Data(seed);
Wipe.String(sbPassword);

```

For more details on the security aspects of the random number generator, see 
the technical details published on our [web site](https://cryptosys.net/pki/ "External link").

[[Contents](#topofpage)] [[Index](#index)]

<a id="distnames"></a>Specifying Distinguished Names
----------------------------------------------------

A *distinguished name* for an X.509 certificate consists of a sequence of *relative distinguished names* (RDN) where each RDN is expressed as an attribute type/value pair.

In this Toolkit, an RDN is specified as an attribute type/value pair in the form `<type>=<value>`,
for example, `CN=Carol`.
Multi-valued RDNs are not supported.
A distinguished name is specified as a string consisting of a sequence of attribute type/value pairs separated by a semicolon (`';'` U+003B).
The general format is 

```
<type>=<value>(;<type>=<value>)*[;]
```

At least one attribute must be specified. 
The RDNs are written to the certificate name in the order they are listed. 
Attribute pairs may be repeated. 
Note that the Windows Certificate Manager displays the attributes in LDAP order, which is the reverse order to which they are written.

<a id="dnsupportedtype"></a>
`<type>` is either a supported short name in the following table or a
	dotted-decimal encoding of an ASN.1 object identifier (see [Specifying an arbitrary RDN](#arbitraryrdn) below).

| type | description | OID |
| --- | --- | --- |
| `CN` | commonName | 2.5.4.3 |
| `SN` | surname | 2.5.4.4 |
| `SERIALNUMBER` | serialNumber | 2.5.4.5 |
| `C` | countryName | 2.5.4.6 |
| `L` | localityName | 2.5.4.7 |
| `ST` or `S` | stateOrProvinceName | 2.5.4.8 |
| `STREET` | streetAddress | 2.5.4.9 |
| `O` | organizationName | 2.5.4.10 |
| `OU` | organizationalUnit | 2.5.4.11 |
| `T` or `TITLE` | title | 2.5.4.12 |
| `G` or `GN` | givenName | 2.5.4.42 |
| `E` | emailAddress *(deprecated)* | 1.2.840.113549.1.9.1 |
| `UID` | userID | 0.9.2342.19200300.100.1.1 |
| `DC` | domainComponent | 0.9.2342.19200300.100.1.25 |
| `initials` | initials | 2.5.4.43 |
| `generationQualifier` | generation qualifier (eg "Jr.") | 2.5.4.44 |
| `dnQualifier` | distinguished name qualifier | 2.5.4.46 |
| `pseudonym` | pseudonym | 2.5.4.65 |

We keep the deprecated `emailAddress` attribute here because it seems so popular. 
Note that the `emailAddress` attribute of the distinguished name
is independent of the `rfc822Name` address in a `subjectAltName` extension, which can be specified 
separately in the extensions parameter.

`<value>` is a string of bytes (octets) to be encoded as an ASN.1 string type. A `<value>` can be specified in the following ways:

Simple form:

:   `<astring>`  

 
where `<astring>` consists only of printable ASCII characters excluding 
the equals sign (`'='` U+003D) and the semicolon (`';'` U+003B). 

Some examples.

```

"C=US;O=Example Organisation;CN=Test User 1"
"CN=Carol"
"CN=My User;O=My Org;OU=Unit;C=AU;L=My Town;S=NSW;E=myuser@my.org"

```

All other characters are treated literally, including spaces after the `'='` and before the `';'`.

General form:

:   `'<quoted-string>'`  

Enclose `<quoted-string>` in single quotes (apostrophe `"'"` U+0027)
and use the backslash (`'\'` U+005C) to escape the special characters 
`"'"` and `"\"`. Examples:

```

"O='e=mc2';OU='roses are red; violets are blue'"
"O='Fred\'s Bar'"      => Fred's Bar
"OU='This=\\E\'asy;'"  => This=\E'asy

```

*[New in v12.0]*.
To insert a single octet in the code of the character, use an *escaped hex sequence* consisting of the backslash `"\"` followed by exactly two hex digits. For example:

```

"C='M\e9xico'"    => Latin-1-encoded letter é
"C='M\C3\A9xico'"  => UTF-8-encoded letter é

```

In all other cases the backslash is ignored.

```

"OU='p\qr'"  => pqr

```

Note that when using C/C++, you need to double-escape the backslash character:

```

strDN = "CN=My User;OU='This=\\\\E\\'asy;';C='M\\C3\\A9xico'";

```

In C#, use a verbatim string literal:

```

strDN = @"CN=My User;OU='This=\\E\'asy;';C='M\C3\A9xico'";

```

Hexadecimal form:

:   `#x<hex-digits>`  

A hex-encoded string of characters preceded by the two characters the hash symbol (number sign '#' U+0023) and 
a lower-case letter x ('x' U+0078). Examples:

```

OU=#x616263         => abc
C=#x4de97869636f    => México in Latin-1
C=#x4dc3a97869636f  => México in UTF-8
CN=#xE5A4A7E58DAB   => CJK ideographs, U+5927 (da) and U+536B (wei) in UTF-8

```

The value must start with the two characters `#x` and be followed only by hex digits `[0-9A-Fa-f]`.
The lower-case letter "x" is case sensitive. This form is now made redundant by using escaped hex sequences in a quoted string, but it's more compact
and, hey, it's there if you want to use it.

Arbitrary RDN:

:   `#<hexstring>`  

 
A hex-encoded string prefixed by a pound sign ('#' U+0023),
where <hexstring> is the hexadecimal encoding of the octets of the DER-encoding of the ASN.1 value,
and only if the <type> is in the form <dotted-oid>.
	*[New in v12.0]* - for advanced users only.	
	See [Specifying an arbitrary RDN](#arbitraryrdn) below.

Special case: Empty subjectName:

:   `$`  

*[New in v12.3]*.
Setting `szDistid="$"` will create an X.509 document with an empty subject name.
At least one field for a subject alternative name extension (`altSubjectName`) must be specified and the extension will automatically be marked critical.
(Note that's a dollar symbol "$", not an empty string, which has a different meaning.)

### <a id="dndefaultencoding"></a>Default encoding

The default encoding is `IA5String` for the `emailAddress` (E) attribute
and `PrintableString` for all other attributes.
If the input string includes characters that are not valid for these encodings, then
a `T61String` (`TeletexString`) will be used instead as a fudge. 
Certificates created with a `T61String` may not be accepted as valid by some profiles.
To force [UTF-8 encoding](#utf8forDN), specify the `PKI_X509_UTF8` flag.

### <a id="utf8forDN"></a>UTF-8 encoding in distinguished names

If the `PKI_X509_UTF8` flag is specified in *nOptions*,
all new DN attribute strings will be encoded as `UTF8String`.

If the UTF-8 flag is set and the value contains only valid UTF-8-encoded characters, then the string will be
copied directly. Otherwise the input is assumed to be 8-bit Latin-1 and will be converted to UTF-8 accordingly,
with each 8-bit character being converted to two UTF-8 bytes.

| Input string | Default encoding | With `PKI_X509_UTF8` |
| --- | --- | --- |
| `OU=abc` | PrintableString "abc" | UTF8String "abc" |
| `OU=#x616263` | PrintableString  "abc" | UTF8String "abc" |
| `OU='a\62c'` | PrintableString  "abc" | UTF8String "abc" |
| `C=M\e9xico` | T61String "México" | UTF8String "México" |
| `C=#x4de97869636f` | T61String "México" | UTF8String "México" |
| `C=#x4dc3a97869636f` | T61String *(garbage!)* | UTF8String "México" |
| `CN=#xE5A4A7E58DAB` | T61String *(garbage!)* | UTF8String (U+5927,U+536B) |
| `CN='\E5\A4\A7\E5\8D\AB'` | T61String *(garbage!)* | UTF8String (U+5927,U+536B) |

The last two examples give the same result as two CJK ideographs, U+5927 (da) and U+536B (wei), encoded in UTF-8. 
See the second example in [`X509_MakeCertSelf`](#X509_MakeCertSelf).

### <a id="arbitraryrdn"></a>Specifying an arbitrary RDN in a distinguished name

*[New in v12.0]*.
To specify a relative distinguished name (RDN) with an attribute type not supported by the short names listed above, 
write the type as a dotted-decimal value (e.g. `2.5.4.18`, *postOfficeBox*)
and the value as a quoted string (e.g. `'Box 45'`).
Alternatively, see [Full DER-encoded Value using "#"](#fullderencoded) below.

> ```
> 
> "C=CA;2.5.4.18='Box 45';CN=John Doe"
> 
> ```

The result of the example above in the final X.509 certificate should be as follows.

```

SEQUENCE {
  SET {
    SEQUENCE {
      OBJECT IDENTIFIER countryName (2 5 4 6)
      PrintableString 'CA'
      }
    }
  SET {
    SEQUENCE {
      OBJECT IDENTIFIER postOfficeBox (2 5 4 18)
      PrintableString 'Box 45'
      }
    }
  SET {
    SEQUENCE {
      OBJECT IDENTIFIER commonName (2 5 4 3)
      PrintableString 'John Doe'
      }
    }
  }

```

For a useful list of RDN attribute types, see [[RFC4519](#RFC4519)] *LDAP Schema for User Applications*.

### <a id="fullderencoded"></a>

Use the representation `<dotted-decimal>=#<hexstring>`
to specify a value that cannot be expressed as a simple string,
with  <hexstring> prefixed by a pound sign ('#' U+0023) with <hexstring> being the hexadecimal encoding of the octets of the DER-encoding of the ASN.1 value.
Note there is just a single pound sign '#' preceding the hex-encoded value. The meaning is different if you use `"#x"`.

> ```
> 
> "C=CA;2.5.4.18=#1306426F78203435;CN=John Doe"
> 
> ```

The expresssion `2.5.4.18=#1306426F78203435` is a convoluted way to demonstrate the use of `<dotted-decimal>=#<hexstring>` 
to represent an RDN attribute-type-and-value.
This creates an RDN of type `postOfficeBox` with ASN.1 value equal to the seven decoded bytes 
`(0x)13 06 42 6F 78 20 34 35`; that is, the PrintableString (tag 0x13), of length six bytes (length byte 0x06), with data representing the string `"Box 45"`
as the six bytes `42 6F 78 20 34 35`.
A simpler equivalent is `2.5.4.18='Box 45'`.

This alternative is meant for advanced users who are comfortable with ASN.1 encodings and want to do something clever like specify the ASN.1 type for the value. 
Using the `'<quoted-string>'` option will almost certainly do what you want in most cases.

### Summary of ways to represent an RDN attribute-type-and-value

| Syntax | Example | Remarks |
| --- | --- | --- |
| <short-name>=<astring> | `OU=abc` | <astring> must not contain `"="` or `";"` |
| <short-name>='<quoted-string>' | `OU='abc' C='M\e9x'` | Surround <quoted-string> with single quotes `"'"`  	and use backslash `"\"` to escape the quote and backslash `\'` and `\\`. 	Use a hex escape sequence `\<HEX><HEX>` of a backslash followed by exactly two hex digits to insert an 8-bit octet. |
| <short-name>=#x<hex-digits> | `OU=#x616263` `C=#x4de978` | <hex-digits> are decoded in pairs directly to octet values. |
| <dotted-decimal>=<quoted-string> | `2.5.4.11='abc'` | <dotted-decimal> must decode to a valid OID; same rules for <quoted-string> as above. |
| <dotted-decimal>=#<hexstring> | `2.5.4.11=#1303616263` | <hexstring> must decode to a full DER-encoding of ASN.1 value (including tag byte and length). |

### Profile limits are not enforced

Various profiles (e.g. PKIX) set limits on the maximum length of the attribute values, 
e.g. the maximum length of the country code "C" is two characters.
We do not enforce these limits. We also do not enforce the strict choices about the string encoding types -
if you pass a character that does not fit in the "correct" encoding for the attribute, we'll kludge it into the most appropriate one. 
In other words, we'll put any old cr*p that you pass into the certificate distinguished name 
(see [AOC policy](#aocpolicy)).

[[Contents](#topofpage)] [[Index](#index)]

<a id="ldapstring"></a>LDAP String Representation of Distinguished Names
------------------------------------------------------------------------

Use the `PKI_X509_LDAP` option with functions 
[X509_CertIssuerName](#X509_CertIssuerName), 
[X509_CertSubjectName](#X509_CertSubjectName) and
[X509_QueryCert](#X509_QueryCert) (with queries "issuerName" and "subjectName")
to obtain the LDAP string representation of the distinguished name as per [[RFC4514](#RFC4514)].

The LDAP string representation lists the RDN `attributeName=attributeValue` pairs 
separated by a comma (`','` U+002C). 
These are output in 'reverse order', i.e.
starting with the last element of the sequence and moving backwards toward the first.

The attribute values are converted to UTF-8 encoding with special and unprintable characters
escaped with a backslash (`'\'` U+005C).
Unprintable characters are output in the form "\xx" where "xx" is the hexadecimal value of the byte.
Special characters that are escaped by a backslash are any of the 7 characters `["+,;<=>]`,
a leading space character, a leading `'#'` character, a trailing space character, 	or the backslash character itself.

The default behaviour is to display only printable ASCII characters and escape all others. 
You can add the `PKI_X509_UTF8` flag to output all multibyte UTF-8 characters in their encoded byte form.
Alternatively you can add the `PKI_X509_LATIN1` flag to convert any UTF-8 characters than can be encoded as a single byte in 
Latin-1 (ISO-8859-1) -  
this is strictly not to the LDAP specification (which requires UTF-8 encoding), 
but you may find it useful for display purposes: you can always save in UTF-8 encoding later.

The only RDN attributeType name strings output by the `PKI_X509_LDAP` option are the nine descriptions required by [[RFC4514](#RFC4514)], namely

* `CN` (commonName, 2.5.4.3)
* `L` (localityName, 2.5.4.7)
* `ST` (stateOrProvinceName, 2.5.4.8)
* `O` (organizationName, 2.5.4.10)
* `OU` (organizationalUnitName, 2.5.4.11)
* `C` (countryName, 2.5.4.6)
* `STREET` (streetAddress, 2.5.4.9)
* `DC` (domainComponent, 0.9.2342.19200300.100.1.25)
* `UID` (userID, 0.9.2342.19200300.100.1.1).

Any other attributeType will be displayed in dotted OID form, e.g. the `emailAddress` attribute type
normally represented by `E` will be output as 
`1.2.840.113549.1.9.1`. 

This LDAP string feature is intended to be used to create an `<X509IssuerName>` element
 or `<X509SubjectName>` element 
within a  
`Signature/KeyInfo/X509Data` element in an XML-DSIG document. 

Note that you cannot use this representation to *specify* a distinguished name when using
[X509_MakeCert](#X509_MakeCert). 
You must use the form described in [Distinguished Names](#distnames).
The LDAP form is just for display.

[[Contents](#topofpage)] [[Index](#index)]

<a id="x509extensions"></a>X.509 Extensions Parameter
-----------------------------------------------------

The *szExtensions* parameter is optional and is used to set advanced options in new X.509 certificates 
and certificate signing requests made using
the [X509_MakeCert](#X509_MakeCert), [X509_MakeCertSelf](#X509_MakeCertSelf) 
and [X509_CertRequest](#X509_CertRequest) functions.
The *szExtensions* parameter is expected to contain a list of one or more  attribute-value pairs of the form 
`type=value` separated by a semicolon (`';'` U+003B) with the type names as defined below.

Valid attribute-value pairs are:

Fields for subject alternative name extension (duplicates OK):

* `rfc822Name`=<*ascii-string*>
* `dNSName`=<*ascii-string*>
* `URI`=<*ascii-string*>
* `iPAddress`=<*dotted-decimal*> or <*IPv6-address*>

Extensions for making X.509 certificates only (duplicates ignored):

* `serialNumber`=<*hex-digits*> | "#x" <*hex-digits*> | "#d" <*digits*>
* `notAfter`=<*iso-date-string*>
* `notBefore`=<*iso-date-string*>
* `subjectKeyIdentifier`=<*hex-digits*>
* `certificatePolicies`=<*dotted-decimal*>
* `cRLDistributionPoints`=<*uri-string*>
* `smimeCapabilities`=<*hexstring[,hexstring,...]*>

Extensions for making X.509 certificates and certificate requests:

* `keyUsage`=<*keyusage-list*>
* `extKeyUsage`=<*extkeyusage-list*>
* <*dotted-decimal*>=#<*hexstring*> 
(advanced users only *[new in v12.0]*. See [Add an arbitrary X.509 Extension](#arbitraryx509extn) below)

The type names are not case sensitive. So, for example, `dnsname` and `DnSnaMe` 
and `dNSName` are all equivalent.

rfc822Name

:   To set the rfc822 email address in the `subjectAltName` extension,
e.g. `rfc822Name=myname@testorg.com`.

dNSName

:   To set the DNS name in the `subjectAltName` extension,
e.g. `dNSName=foo.example.net`.

URI

:   To set the Uniform Resource Identifier in the `subjectAltName` extension,
e.g. `uri=http://www.ietf.org/rfc/rfc3986.txt`.

iPAddress

:   To set the IP address in the `subjectAltName` extension,
e.g. `iPAddress=192.168.15.1` or `iPAddress=2001:db8:85a3:0:0:8a2e:370:7334`.
IPv4 addresses *must* be in dotted-quad format `d.d.d.d` using exactly four decimal integers of value between 0 and 255.
IPv6 addresses *must* be in the form `x:x:x:x:x:x:x:x`, exactly 8 groups of one to four hexadecimal digits separated by colons. 
The compressed zero form using `"::"` is not accepted. 
Alternatively, IPv6 addresses may be specified in the base-85 notation of [[RFC1924](#RFC1924)]!

serialNumber

:   To override the serial number set by *nCertNum* with a larger, unlimited-length
integer represented in hexadecimal format, e.g. `serialNumber=12deadbeefcafe0123` 
(the decimal number 348087084311274979619). 
If the first hex digit is greater than 7, it will preceded by a '00' to make sure the integer is stored as a positive value.
*[New in v11.0]*
Add the prefix "#d" to specify the serial number as a large decimal integer, 
e.g. `serialNumber=#d348087084311274979619`,
or add the prefix "#x" to specify unambiguously the serial number as a hexadecimal-encoded integer,
e.g. `serialNumber=#x12deadbeefcafe0123`. 
If no "#" prefix is found, the default is to assume hexadecimal encoding.

notAfter

:   To override the validity period set by *nYearsValid* with a specific date and time in 
[ISO format](#iso8601datetime), 
e.g. `notAfter=2030-12-31` or `notAfter=2030-12-31T14:03:59`. 
If no time is given it will default to 23:59:59.
Note that this time is UTC (GMT) not local.

notBefore

:   To override the default start time from one minute ago to a specific date and time in ISO format
[ISO format](#iso8601datetime), 
e.g. `notBefore=2008-12-31`. 
If no time is given it will default to 00:00:01.
Note that this time is UTC (GMT) not local.

subjectKeyIdentifier

:   To set the `subjectKeyIdentifier` extension with an octet string (binary) value specified in hex format
e.g. `subjectKeyIdentifier=fedcba9876543210`.

certificatePolicies

:   To set the `certificatePolicies` extension with a *single* policy information term with an object
identifier (OID) in dotted form,
e.g. `certificatePolicies=2.16.840.1.101.3.2.1.48.1`.
Only one policy information term can be specified and no qualifiers are permitted.

cRLDistributionPoints

:   *[New in v20.7]*
To set the `cRLDistributionPoints` extension with a *single* `DistributionPoint`,
e.g. `cRLDistributionPoints=http://dodgycert.example.com/evca.crl`.
Only one distributionPoint can be specified and it *must* be a general name of type URI.

smimeCapabilities

:   *[New in v20.5]*
To set the `smimeCapabilities` extension with one or more `SMIMECapability` provide a list of one or more hexadecimal strings, separated by commas ",".
Each hexstring must be a hexadecimal representation of the DER-encoded ASN.1 value of the `SMIMECapability` (which will always begin with "30").
The S/MIME Capabilities Extension is defined in [[RFC4262](#RFC4262)]. 
For examples of DER encodings see section 6 of [[RFC5753](#RFC5753)] and section 8 of [[RFC8418](#RFC8418)].

For example, `sMIMECapabilities=300B0609608648016503040102,301A060B2A864886F70D0109100313300B0609608648016503040105;`
will set two `smimeCapability` nodes, one for `aes128-CBC` and the other for "ECDH with HKDF using SHA-256" (`ecdhHKDF-SHA256`) with `aes128-wrap` as the key wrapping algorithm.

| ```  SEQUENCE {   OBJECT IDENTIFIER sMIMECapabilities (1 2 840 113549 1 9 15)   OCTET STRING, encapsulates {     SEQUENCE {       SEQUENCE {         OBJECT IDENTIFIER aes128-CBC (2 16 840 1 101 3 4 1 2)       }       SEQUENCE {         OBJECT IDENTIFIER ecdhHKDF-SHA256 (1 2 840 113549 1 9 16 3 19)         SEQUENCE {           OBJECT IDENTIFIER aes128-wrap (2 16 840 1 101 3 4 1 5)           }         }       }     }   }  ``` | ```  30 38  --SEQUENCE/56=0x38    06 09  --OBJECTIDENTIFIER/9=0x9       2a 86 48 86 f7 0d 01 09 0f       --sMIMECapabilities (1.2.840.113549.1.9.15)    04 2b  --OCTETSTRING/43=0x2B       --encapsulates:       30 29  --SEQUENCE/41=0x29          30 0b  --SEQUENCE/11=0xB             06 09  --OBJECTIDENTIFIER/9=0x9                60 86 48 01 65 03 04 01 02                --aes128-CBC (2.16.840.1.101.3.4.1.2)          30 1a  --SEQUENCE/26=0x1A             06 0b  --OBJECTIDENTIFIER/11=0xB                2a 86 48 86 f7 0d 01 09 10 03 13                --ecdhHKDF-SHA256 (1.2.840.113549.1.9.16.3.19)             30 0b  --SEQUENCE/11=0xB                06 09  --OBJECTIDENTIFIER/9=0x9                   60 86 48 01 65 03 04 01 05                   --aes128-wrap (2.16.840.1.101.3.4.1.5)  ``` |
| --- | --- |

keyUsage

:   *[New in v11.0]*
	To set the keyUsage extension bits, specify a comma-separated list of any of the following keywords from [[PKIX](#PKIX)] s4.2.1.3.

> ```
> 
> digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly, decipherOnly.
> 
> ```

For example, `"keyUsage=digitalSignature,nonRepudiation;"`.
Careful, for X.509 certificates, these will add to any values in *nKeyUsageFlags*.

By default, the keyUsage extension is marked critical (as per [[PKIX](#PKIX)]: 
"When present, conforming CAs SHOULD mark this extension as critical").
  

*[New in v20.0]* To mark this extension as non-critical, include the key word `noncritical` in the attribute value,
e.g. `"keyUsage=keyAgreement,noncritical;"`.

extKeyUsage

:   *[New in v12.3]*
To set extKeyUsage extension purposes, specify a comma-separated list of any of the following keywords from [[PKIX](#PKIX)] s4.2.1.12.
(Note that the special KeyPurposeId `anyExtendedKeyUsage` is not supported.)

> ```
> 
> serverAuth, clientAuth, codeSigning, emailProtection, timeStamping, OCSPSigning.
> 
> ```

To make the extension critical, append `",critical"`. 

For example, `"extKeyUsage=serverAuth,clientAuth,emailProtection,critical;"`.

Some examples of valid input strings to the *szExtensions* parameter:

```

"rfc822name=AliceRSA@example.com"
"serialNumber=46346BC7800056;subjectKeyIdentifier=77D2B4D1B74C8A8AA3CE"
"rfc822Name=me@here.com;notAfter=2020-12-31T12:00:59"
"rfc822Name=AliceRSA@example.com;notBefore=1999-09-19T01:08:47;notAfter=2039-12-31"
"dnsname=foo.example.net;uri=ftp://ftp.is.co.za/rfc/rfc1808.txt;ipaddress=127.0.0.1"
"AliceRSA@example.com"   // (legacy behaviour=>rfc822Name)

```

Space characters are significant between the `'='` and the `';'`, 
so the following examples will produce different results.

```

dnsname=foo.example.com;
dnsname= foo.example.com;
dnsname=foo.example.com ;

```

If an attribute is not specified, the relevant field
will either be omitted or will default to the values set by *nCertNum*,
*nYearsValid* and the current system time.

It is an error to specify an invalid attribute name. 
The attributes meant only for making X.509 certificates are not accepted for certificate signing requests,
and any duplicates of the X.509-only attributes will be ignored.

The values of ASCII strings will be copied exactly as given without any further checks, regardless of whether or not they are suitable.
For example, we don't check that the value passed for an `rfc822Name` is actually a valid email address.
It's up to the user to police the input to this rather sharp tool. See our [AOC Policy](#aocpolicy) below.

### <a id="arbitraryx509extn"></a>Add an arbitrary X.509 Extension

*[New in v12.0]* To add an arbitrary Extension to a version 3 X.509 certificate, include an attribute-value pair of the form
<*dotted-decimal*>=#<*hexstring*> in the *szExtensions* parameter.
Where <*dotted-decimal*> is a dotted decimal OID value representing the `extnID` of the Extension
and <*hexstring*> is the hexadecimal encoding of each byte of the DER-encoded ASN.1 value of the `extnValue`,
excluding the encapsulating OCTET STRING tag and length bytes (if you don't understand this, don't use it).

Examples

> ```
> 
> "2.16.840.1.113730.1.1=#03020410;"	
> 
> ```

`2.16.840.1.113730.1.1` represents the OID for `netscape-cert-type` and `03020410` is the hexadecimal encoding of the
DER-encoded ASN.1 value BIT STRING with 4 unused bits: '1000'B.

> ```
> 
> "2.5.29.31=#302d302ba029a0278625687474703a2f2f646f646779636572742e6578616d706c652e636f6d2f657663612e63726c;"	
> 
> ```

`2.5.29.31` represents the OID for `cRLDistributionPoints` and <*hexstring*> is the hexadecimal encoding of the
ASN.1 value:

```

SEQUENCE {
. SEQUENCE {
. . [0] {
. . . [0] {
. . . . [6] 'http://dodgycert.example.com/evca.crl'
. . . . }
. . . }
. . }
. }

```

Advanced users only. It's up to you to compose a valid DER-encoded ASN.1 value. And, yes, you can use this feature to add an MPEG video of your cat to an X.509 certificate!

*[New in v12.3]* To make an arbitrary extension critical, append `",critical"` to the hexstring component (no spaces, lowercase only). 
For example

> ```
> 
> "2.5.29.17=#30068704c0a80f01,critical;"	
> 
> ```

This will add a critical `subjectAltName` extension (OID 2.5.29.17) with the value `IP Address=192.168.15.1`.

```

SEQUENCE {
. OBJECT IDENTIFIER subjectAltName (2 5 29 17)
. BOOLEAN TRUE
. OCTET STRING, encapsulates {
. . SEQUENCE {
. . . [7] C0 A8 0F 01
. . . }
. . }
. }
}

```

[[Contents](#topofpage)] [[Index](#index)]

<a id="aocpolicy"></a>AOC policy for X.509 content
--------------------------------------------------

This toolkit is a set of tools to do specific cryptographic procedures that should be useful in your applications.
We do not police too strongly what you do, providing the input parses OK.
In particular, you can use the functions and options in here to create all sorts of wierd and wonderful
X.509 certificates.
Our policy is simple, we accept *any old cr*p* (AOC) you want to pass. 
It's up to you to restrict the input to whatever profile you wish to adopt.

Coming soon: `addMpegVideoOfCat` option :-)  

*[New in v12.0]* Oh, yes, you can now! See [Add an arbitrary X.509 Extension](#arbitraryx509extn).

(And we used "AOC" many years before the election of any politician with the same moniker.)

[[Contents](#topofpage)] [[Index](#index)]

<a id="iso8601datetime"></a>ISO 8601 date-time formats
------------------------------------------------------

Functions that require a date-time to be specified in ISO 8601 format (<iso-date-string>) will accept the following formats.

```

Year:
   YYYY (eg 2013, defaults to 2013-01-01)
Year and month:
   YYYY-MM (eg 2013-07, defaults to 2013-07-01)
Complete date:
   YYYY-MM-DD (eg 2013-07-16)
Complete date plus hours with optional "Z":
   YYYY-MM-DDThh  (eg 2013-07-16T19,  defaults to 2013-07-16T19:00:00Z)
   YYYY-MM-DDThhZ (eg 2013-07-16T19Z, defaults to 2013-07-16T19:00:00Z)
Complete date plus hours and minutes with optional "Z":
   YYYY-MM-DDThh:mm  (eg 2013-07-16T19:23,  defaults to 2013-07-16T19:23:00Z)
   YYYY-MM-DDThh:mmZ (eg 2013-07-16T19:23Z, defaults to 2013-07-16T19:23:00Z)
Complete date plus hours, minutes and seconds with optional "Z":
   YYYY-MM-DDThh:mm:ss  (eg 2013-07-16T19:23:51, defaults to 2013-07-16T19:23:51Z)
   YYYY-MM-DDThh:mm:ssZ (eg 2013-07-16T19:23:51Z)

```

where

```

YYYY = four-digit year
MM   = two-digit month (01=January, etc.)
DD   = two-digit day of month (01 through 31)
hh   = two digits of hour (00 through 23) (am/pm NOT allowed)
mm   = two digits of minute (00 through 59)
ss   = two digits of second (00 through 59)
Z    = special UTC designator ("Z") (optional)

```

Times are *always* interpreted as GMT (UTC) times regardless of whether a "Z" time zone designator is appended or not.
Time zone designators of the form "+hh:mm" are not accepted. 
Years before 1900 are not accepted (so, sorry, no X.509 certs for Julius Caesar).
Be careful, if you examine the resulting files in another time zone using other tools, like Windows Certificate Manager,
the times may display differently in local time. This is not an error.

[[Contents](#topofpage)] [[Index](#index)]

<a id="asn1objects"></a>ASN.1 objects: binary DER- and BER-encoded files vs PEM-encoded text files
--------------------------------------------------------------------------------------------------

Almost all the security-related files used by this toolkit - X.509 certificates, key files, CMS data files and so forth -
contain ASN.1 objects encoded in BER- or DER-encoding. You'll also come across PEM-encoded files.
This section attempts to explain the differences and similarities between these terms.

### Some definitions

ASN.1 (Abstract Syntax Notation One)

:   ASN.1 (Abstract Syntax Notation One) is a formal but flexible notation that allows you to specify abstract objects used in 
high-level telecommunications protocols. 
You can build up definitions of complex types using simple types like integers and bit strings together with structured 
types such as sets and sequences.

Basic Encoding Rules (BER)

:   BER describes how to represent or encode values of each ASN.1 type as a string of eight-bit octets. 
There is generally more than one way to BER-encode a given value.

Distinguished Encoding Rules (DER)

:   Distinguished Encoding Rules (DER) is a subset of BER which gives a unique encoding to each ASN.1 value.

For most purposes here, you can consider "BER-encoded" and "DER-encoded" to mean the same thing.

DER- and BER-encoded files are binary files. 
A PEM file is an alternative way to encode the same data in a text format
(these are also referred to as "Textual Encodings", see [[RFC7468](#RFC7468)]).
PEM encoding is the base64 encoding [[RFC4648](#RFC4648)] of the DER-encoded data sandwiched between the encapsulating boundaries of the form
`"-----BEGIN XXX-----"` and `"-----END XXX-----"`. For example,

```

-----BEGIN CERTIFICATE-----
MIHgMIGaAgEBMA0GCSqG...
-----END CERTIFICATE-----

```

PEM-encoded files are conventionally meant to be named `.pem` but can have `.txt` or the same
extension as their DER-encoded sibling, e.g. `.cer`. We don't care. Having a `.txt` extension
makes it easy to examine the file.
Note that we ignore the actual label in the encapsulation: we decode the inner base64 and examine the decoded bytes directly.
Other applications may not be so tolerant.

In this toolkit, where the input requires a file, 
we accept both DER-encoded binary files and their equivalent PEM-encoded text files automatically.
We also in general accept the same data files encoded with BER-encoding.
In addition, you can pass the PEM-encoded data in a string (a **PEM String**) instead of passing a filename. 
See [PEM string alternative](#pemstring).

### Exception

We do not accept the really old encrypted form of PEM files with "Proc-Type" parameters that look like

```

-----BEGIN EC PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,085FFED98A156DBB

hPvIVkMx6lMS3JB6so8d8JHt+...
-----END EC PRIVATE KEY-----

```

But we do accept the modern form with just base64 characters sandwiched between the 
`"-----BEGIN XXX-----"` and `"-----END XXX-----"` boundaries, for example.

```

-----BEGIN ENCRYPTED PRIVATE KEY-----
MIICojAcBgoqhkiG9w0BDAEDMA4ECHPQz6NdAmoFAgIH0ASCAoBKn9KXr+dm
Vtc0ZhEog7t3Prs4rJazwUsXExU78ePLMquxLi/cPmqtyjb472r6XUOa...
-----END ENCRYPTED PRIVATE KEY-----

```

### Example

An RSA public key is represented with the ASN.1 type `RSAPublicKey` specified in PKCS#1 [[RFC3447](#RFC3447)]

```

RSAPublicKey ::= SEQUENCE {
    modulus           INTEGER,  -- n
    publicExponent    INTEGER   -- e
}

```

Example key file formatted by DUMPASN1:

```

  0  71: SEQUENCE {
  2  64: . INTEGER
       : . . 0A 66 79 1D C6 98 81 68 DE 7A B7 74 19 BB 7F B0
       : . . C0 01 C6 27 10 27 00 75 14 29 42 E1 9A 8D 8C 51
       : . . D0 53 B3 E3 78 2A 1D E5 DC 5A F4 EB E9 94 68 17
       : . . 01 14 A1 DF E6 7C DC 9A 9A F5 5D 65 56 20 BB AB
 68   3: . INTEGER 65537
       : . }

```

The same key formatted by the [ASN1_TextDump](#ASN1_TextDump) function:

```

30 47  --SEQUENCE/71=0x47
   02 40  --INTEGER/64=0x40
      0a 66 79 1d c6 98 81 68 de 7a b7 74 19 bb 7f b0
      c0 01 c6 27 10 27 00 75 14 29 42 e1 9a 8d 8c 51
      d0 53 b3 e3 78 2a 1d e5 dc 5a f4 eb e9 94 68 17
      01 14 a1 df e6 7c dc 9a 9a f5 5d 65 56 20 bb ab
   02 03  --INTEGER/3=0x3
      01 00 01
      --65537
--(73 bytes)

```

A hex dump of the raw bytes:

```

000000  30 47 02 40 0a 66 79 1d c6 98 81 68 de 7a b7 74  0G.@.fy....h.z.t
000010  19 bb 7f b0 c0 01 c6 27 10 27 00 75 14 29 42 e1  .......'.'.u.)B.
000020  9a 8d 8c 51 d0 53 b3 e3 78 2a 1d e5 dc 5a f4 eb  ...Q.S..x*...Z..
000030  e9 94 68 17 01 14 a1 df e6 7c dc 9a 9a f5 5d 65  ..h......|....]e
000040  56 20 bb ab 02 03 01 00 01                       V .......

```

The same key data in PEM-encoding:

```

-----BEGIN RSA PUBLIC KEY-----
MEcCQApmeR3GmIFo3nq3dBm7f7DAAcYnECcAdRQpQuGajYxR0FOz43gqHeXcWvTr
6ZRoFwEUod/mfNyamvVdZVYgu6sCAwEAAQ==
-----END RSA PUBLIC KEY-----

```

*All* ASN.1 objects used for security applications consist of an outer SEQUENCE wrapping the data inside.
That means the first byte in a binary DER-encoded object will always be 0x30 (the tag value for a SEQUENCE),
and the first letter in a base64/PEM encoding will be the letter capital 'M'.

[[Contents](#topofpage)] [[Index](#index)]

<a id="base64forcert"></a>Base64 alternative for X.509 certificates
-------------------------------------------------------------------

Those X.509 functions which require you to pass the filename of an X.509 certificate
will accept a base64 string representation of the certificate instead.
This is the base64 string that can be obtained using the
[`X509_ReadStringFromFile`](#X509_ReadStringFromFile) function.
The first character in such a string should always be an "M".

You can also pass a string containing the certificate in PEM format. 
See [PEM string alternative](#pemstring) below for more details. 

The example below shows how each of the filename,
the base64 string, or the PEM-format string can be used in a typical X.509 function.

```

Dim nRet As Long
Dim strCertFileOrB64String As String
Dim strHexHash As String

' Compute the SHA-1 `thumbprint' of an X.509 certificate in two forms
strHexHash = String(PKI_SHA1_CHARS, " ")

' Refer to file itself...
strCertFileOrB64String = "smallca.cer"
nRet = X509_CertThumb(strCertFileOrB64String, strHexHash, Len(strHexHash), 0)
Debug.Print "X509_CertThumb returns " & nRet & " for '" & strCertFileOrB64String & "'"
Debug.Print "SHA-1 thumbprint=" & strHexHash

' Use base64 string representation directly...
strCertFileOrB64String = _
    "MIHgMIGaAgEBMA0GCSqGSIb3DQEBBQUAMAwxCjAIBgNVBAMTAUEwHhcNMDcwODAyMDIwMDAxWhc" _
    & "NMTEwODAyMDIwMDAxWjAMMQowCAYDVQQDEwFBMEowDQYJKoZIhvcNAQEBBQADOQAwNgIxA1KS" _
    & "JlPSmQAqQgDHUISaUsCrHbIZe249i6jFtfN3rA7czrP4CXS3mjvMFf0AsxV6BwIBAzANBgkqh" _
    & "kiG9w0BAQUFAAMyAACeT7GtgmBRKUN20cIyNEGneEvmNxaliuBEVkg2npbyEBgeHXOH6jqj9Ase348UN/Q="
nRet = X509_CertThumb(strCertFileOrB64String, strHexHash, Len(strHexHash), 0)
Debug.Print "X509_CertThumb returns " & nRet & " for '" & strCertFileOrB64String & "'"
Debug.Print "SHA-1 thumbprint=" & strHexHash

' Again using a PEM-style string...
strCertFileOrB64String = _
    "-----BEGIN CERTIFICATE-----" & vbCrLf _
    & "MIHgMIGaAgEBMA0GCSqGSIb3DQEBBQUAMAwxCjAIBgNVBAMTAUEwHhcNMDcwODAyMDIwMDAxWhc" & vbCrLf _
    & "NMTEwODAyMDIwMDAxWjAMMQowCAYDVQQDEwFBMEowDQYJKoZIhvcNAQEBBQADOQAwNgIxA1KS" & vbCrLf _
    & "JlPSmQAqQgDHUISaUsCrHbIZe249i6jFtfN3rA7czrP4CXS3mjvMFf0AsxV6BwIBAzANBgkqh" & vbCrLf _
    & "kiG9w0BAQUFAAMyAACeT7GtgmBRKUN20cIyNEGneEvmNxaliuBEVkg2npbyEBgeHXOH6jqj9Ase348UN/Q=" & vbCrLf _
    & "-----END CERTIFICATE-----"
nRet = X509_CertThumb(strCertFileOrB64String, strHexHash, Len(strHexHash), 0)
Debug.Print "X509_CertThumb returns " & nRet & " for '" & strCertFileOrB64String & "'"
Debug.Print "SHA-1 thumbprint=" & strHexHash

```

*[As of v3.5, the `vbCrLf` CRLF characters are no longer required in the PEM-style string]*

```

X509_CertThumb returns 40 for 'smallca.cer'
SHA-1 thumbprint=a36b1bfa0af41a2785066b2d5135b67011ac3b7f
X509_CertThumb returns 40 for 'MIHgMIGaAgEBMA0GCSq...(snip)...HXOH6jqj9Ase348UN/Q='
SHA-1 thumbprint=a36b1bfa0af41a2785066b2d5135b67011ac3b7f
X509_CertThumb returns 40 for '-----BEGIN CERTIFICATE-----
MIHgMIGaAgEBMA...(snip)...BgeHXOH6jqj9Ase348UN/Q=
-----END CERTIFICATE-----'
SHA-1 thumbprint=a36b1bfa0af41a2785066b2d5135b67011ac3b7f

```

[[Contents](#topofpage)] [[Index](#index)]

<a id="pemstring"></a>PEM string alternative for X.509 certificates, RSA and EC keys, etc
-----------------------------------------------------------------------------------------

In the same way you can pass a base64 string instead of an X.509 filename, you can 
pass a string containing the certificate in PEM format. The PEM format looks like 

```

-----BEGIN CERTIFICATE-----
MIHgMIGaAgEBMA0GCSqG...
-----END CERTIFICATE-----

```

Similarly, those RSA and ECC functions which require you to pass the filename of an key file
will accept a string that contains the file contents in PEM format. An key file in PEM format looks like 

```

-----BEGIN ENCRYPTED PRIVATE KEY-----
MIICojAcBgoqhkiG9w0BDAEDMA4ECHPQz6NdAmoFAgIH0ASCAoBKn9KXr+dm
Vtc0ZhEog7t3Prs4rJazwUsXExU78ePLMquxLi/cPmqtyjb472r6XUOa...
-----END ENCRYPTED PRIVATE KEY-----

```

*[New in v3.5]* Similarly for [CMS objects](#cmsbase64pem).

The functions will accept all strings that start with "-----BEGIN" and are of the form

```

-----BEGIN FOO BAR-----
(base64-encoded data)
-----END FOO BAR-----

```

The exact word or words used for "FOO BAR" in the "BEGIN FOO BAR" and "END FOO BAR" labels do not matter 
(at least as far as we are concerned; other applications may object), 
but there must be exactly 5 hyphen (minus) characters "-" before and after the label. 
Any non-base64 characters found in the encoded data, including newline characters or spaces, will be ignored.

White space is ignored in the PEM string input, so there is no need to add LF or CRLF newlines at the end of each line.
You can input the data as one continuous line of characters, for example.

```

strPem = "-----BEGIN FOO-----MIICojAcBgoqhkiG9w0BDAEDMA4E...(snip)...se348UN/Q=-----END FOO-----"

```

This means, for example, that you can store your certificates and encrypted private keys as strings in a database.
Note that an X.509 certificate can be passed either as a plain base64 string or in PEM format; that is, both 
with and without the "-----BEGIN CERTIFICATE-----" encapsulation; but RSA key data can *only*
be passed in PEM format.

### Example

This example shows how an encrypted private key can be read from a string instead of a file.

```

Dim strKeyPemData As String
strKeyPemData = _
  "-----BEGIN ENCRYPTED PRIVATE KEY-----" & _
  "MIICojAcBgoqhkiG9w0BDAEDMA4ECHPQz6NdAmoFAgIH0ASCAoBKn9KXr+dm" & _
  "Vtc0ZhEog7t3Prs4rJazwUsXExU78ePLMquxLi/cPmqtyjb472r6XUOa9J/v" & _
  "g2gYHlJ7D7FfAdTdVbHmXWfZzdIqI+AKZmrMoIfSVSSrI8mLDXLDgJVm2Gxa" & _
  "r/YJ154L4fwqWjj0b06v8nTrXTp7G3ZSxjmXc3auf8tS1RatpDuSn027jBGt" & _
  "Pg2CGPjeSomOU7Efd89R+gryW3RfXaMEv1TtGmdS+szxN4TAzgFTzjzE7qJ2" & _
  "+WL09hBRxSyi5JybbxblrO5zDbGJD8rq4kGawWUj4PYDpOkxQYQyK/cALEvv" & _
  "EipLeWvk03CadKER3EcpL7wQT3N5wJGNx7GR3efkO7lO/VfGf6kYFsJ8Qt94" & _
  "vBlgq84abgSD+rlRX03re/NLJQ00Qxl3bDrkSiRoXSfBiOeVzBVTsh03Sj4B" & _
  "V0v2KLENsMXr40rMqTGfKD3V+FyYUehWEkEl3NrIVpBSJir+g4H3tl76SdNe" & _
  "mq/cTtQP+EY8fpC3I46dyDXFat3wQfubw+E5nGfv7xp6vRVRRolpZx7DpuB/" & _
  "z1tzO3uP0vJ0pjATriO/ZAVs6UrXx+DJ6XsfrAVt0jpW5Ngr8rm2EiD3/1T9" & _
  "7q1dELJ7GzCY1dG99XVjt9ZXb7cI8zsPpT/gzQJLfeLe3U5Mdw0hKZLfPCex" & _
  "0urs3ytK0XNu+jZAYeSaysG8/rHJaH74WOgJ8gnSPY4QtWsu6+3qBErS2jbq" & _
  "7E2jRvBKWICVd1yiQCDq/c6s9LeYhNhZsmcWxuX9b4lG9f1LHZy0djhIYi4x" & _
  "IpcEfjkTH+7zUOkMQ+fXZHtSEVFt9L2Ci49jB8YReqbfOuDFzzwsk3xxfL2h" & _
  "ZoRK" & _
  "-----END ENCRYPTED PRIVATE KEY-----"
Dim nLen As Long
Dim strPassword As String
Dim strPrivateKey As String
strPassword = "password"
' How long is PrivateKey string?
nLen = RSA_ReadEncPrivateKey("", 0, strKeyPemData, strPassword, 0)
If nLen <= 0 Then
  Debug.Print "ERROR: RSA_ReadEncPrivateKey returns " & nLen
  Exit Sub
End If
' Pre-dimension the string to receive data
strPrivateKey = String(nLen, " ")
' Read in the Private Key
nLen = RSA_ReadEncPrivateKey(strPrivateKey, Len(strPrivateKey), strKeyPemData, strPassword, 0)
If nLen <= 0 Then
  Debug.Print "ERROR: RSA_ReadEncPrivateKey returns " & nLen
  Exit Sub
End If
' ... do something with the private key...
Debug.Print "Private key is " & RSA_KeyBits(strPrivateKey) & " bits long."
Debug.Print "KeyHashCode=" & Hex(RSA_KeyHashCode(strPrivateKey))
' then make sure it is deleted
strPrivateKey = wipeString(strPrivateKey)

```

This should produce the output

```

Private key is 1024 bits long.
KeyHashCode=48BFEF2C

```

The same using C# with a verbatim string:

```

string s = @"-----BEGIN ENCRYPTED PRIVATE KEY----- 
MIICojAcBgoqhkiG9w0BDAEDMA4ECHPQz6NdAmoFAgIH0ASCAoBKn9KXr+dm 
Vtc0ZhEog7t3Prs4rJazwUsXExU78ePLMquxLi/cPmqtyjb472r6XUOa9J/v 
g2gYHlJ7D7FfAdTdVbHmXWfZzdIqI+AKZmrMoIfSVSSrI8mLDXLDgJVm2Gxa 
r/YJ154L4fwqWjj0b06v8nTrXTp7G3ZSxjmXc3auf8tS1RatpDuSn027jBGt 
Pg2CGPjeSomOU7Efd89R+gryW3RfXaMEv1TtGmdS+szxN4TAzgFTzjzE7qJ2 
+WL09hBRxSyi5JybbxblrO5zDbGJD8rq4kGawWUj4PYDpOkxQYQyK/cALEvv 
EipLeWvk03CadKER3EcpL7wQT3N5wJGNx7GR3efkO7lO/VfGf6kYFsJ8Qt94 
vBlgq84abgSD+rlRX03re/NLJQ00Qxl3bDrkSiRoXSfBiOeVzBVTsh03Sj4B 
V0v2KLENsMXr40rMqTGfKD3V+FyYUehWEkEl3NrIVpBSJir+g4H3tl76SdNe 
mq/cTtQP+EY8fpC3I46dyDXFat3wQfubw+E5nGfv7xp6vRVRRolpZx7DpuB/ 
z1tzO3uP0vJ0pjATriO/ZAVs6UrXx+DJ6XsfrAVt0jpW5Ngr8rm2EiD3/1T9 
7q1dELJ7GzCY1dG99XVjt9ZXb7cI8zsPpT/gzQJLfeLe3U5Mdw0hKZLfPCex 
0urs3ytK0XNu+jZAYeSaysG8/rHJaH74WOgJ8gnSPY4QtWsu6+3qBErS2jbq 
7E2jRvBKWICVd1yiQCDq/c6s9LeYhNhZsmcWxuX9b4lG9f1LHZy0djhIYi4x 
IpcEfjkTH+7zUOkMQ+fXZHtSEVFt9L2Ci49jB8YReqbfOuDFzzwsk3xxfL2h 
ZoRK 
-----END ENCRYPTED PRIVATE KEY-----";
StringBuilder sbKeyCheck = Rsa.ReadPrivateKey(s, "password");
Console.WriteLine("Private key is " + Rsa.KeyBits(sbKeyCheck.ToString()) + " bits long");
Console.WriteLine("KeyHashCode={0,8:X}", Rsa.KeyHashCode(sbKeyCheck.ToString()));
Wipe.String(sbKeyCheck);

```

```

Private key is 1024 bits long
KeyHashCode=48BFEF2C

```

[[Contents](#topofpage)] [[Index](#index)]

<a id="cmsbase64pem"></a>Base64 and PEM string alternatives for CMS objects
---------------------------------------------------------------------------

*[New in v3.5]*
All functions that read a signed-data or enveloped-data CMS object will now accept the data in the *szFileIn* parameter in five forms.

1. Specify a filename

:   The file may contain data in one of three formats
1. BER-encoded binary data
2. PEM-encoded data (a PEM file)
3. Base64-encoded data

2. Pass the data in a string

:   The string may contain data in one of two formats
1. PEM-encoded data (a PEM string)
2. Base64-encoded data

PEM format is base64-encoded data encapsulated inside `"-----BEGIN FOO-----"` and `"-----END FOO-----"` boundaries.
See [PEM string](#pemstring) above. For example,

```

-----BEGIN PKCS7-----
MIAGCSqGSIb3DQEHAqCAMIACAQExADCABgkqhkiG9w0BBwGggCSABARUaGlzBBggaXMgc29
tZSBzYW1wbGUgY29udGVudC4AAAAAAAAxDjAMAgEBMAAwADAABAH9AAAAAAAA
-----END PKCS7-----

```

These filename-or-string forms are detected automatically and there is no longer any need 
*[as of v3.5]* to use the `PKI_CMS_FORMAT_BASE64` option flag.
One possible conflict could be if you are in the habit of naming files in the form `"MAQwAgUA"` without any "." extension
and pass a string that corresponds to an existing file in the current directory.
In that unlikely event, we will use the file.

However, if you use the `PKI_BIG_FILE` option, you *must* pass the filename of a BER-encoded binary file.

[[Contents](#topofpage)] [[Index](#index)]

<a id="cipheralgmode"></a>Specifying the algorithm, mode and padding for generic block cipher functions
-------------------------------------------------------------------------------------------------------

The generic block cipher functions `CIPHER_Byte`, `CIPHER_Hex` and `CIPHER_File` 
allow the block cipher algorithm and mode to specified 
*either* by a *szAlgAndMode* string *or* by using the *nOptions* flags, but not both.
The algorithm-and-mode parameter string combines the name of the block cipher algorithm and the mode, 
e.g. `"tdea/ecb"`. 
The output from the `CIPHER_Byte` and `CIPHER_Hex` functions is *always* the same length as the input, and
any padding required for ECB and CBC modes must be dealt with separately
using the `PAD_*` functions. 

The  functions `CIPHER_EncryptBytes` and `CIPHER_DecryptBytes`
use the string parameter *szAlgModePad* 
to specify the method of padding as well, e.g. `"aes128/cbc/pkcs5padding"`.
With `CIPHER_EncryptBytes` the output will be longer than the input if padding is to be added.
The user must query the function first to find the correct padded length and then allocate a buffer before encrypting.

Valid algorithm names are:

| Value | Algorithm | Option |
| --- | --- | --- |
| `tdea` | Triple DES, a.k.a. 3DES, des-ede3 | `PKI_BC_TDEA` |
| `3des` | Alternative for Triple DES | `PKI_BC_3DES` |
| `desede3` | Another alternative for Triple DES (`desede` is OK) | `PKI_BC_DESEDE3` |
| `aes128` | AES-128 | `PKI_BC_AES128` |
| `aes192` | AES-192 | `PKI_BC_AES192` |
| `aes256` | AES-256 | `PKI_BC_AES256` |

We have used "TDEA" consistently in CryptoSys products
to refer to the Triple DES algorithm (as in its official name "Triple Data Encryption Algorithm").
In this case, you can use
any one of "tdea", "3des" or "desede3" (or "desede"). These are all equivalent and all yield identical results.

Valid mode names are:

| Value | Mode | Option |
| --- | --- | --- |
| `ecb` | Electronic Code Book mode (default) | `PKI_MODE_ECB` |
| `cbc` | Cipher Block Chaining mode | `PKI_MODE_CBC` |
| `ofb` | Output Feedback mode | `PKI_MODE_OFB` |
| `cfb` | 64/128-bit† Cipher Feedback mode | `PKI_MODE_CFB` |
| `ctr` | Counter mode | `PKI_MODE_CTR` |
| `gcm` | Galois/Counter mode‡ | `PKI_MODE_GCM` |

† Only 64-bit CFB mode is provided for Triple DES and only 128-bit CFB mode is provided for AES.

‡ GCM is only available for AES, and only for some functions.

Some examples of valid string values for the *szAlgAndMode* parameter are:

| strAlgAndMode | Description | Alternative Option value |
| --- | --- | --- |
| `tdea-cbc` | Triple DES in CBC mode | `PKI_BC_TDEA+PKI_MODE_CBC` |
| `3des-cbc` | ditto | `PKI_BC_3DES+PKI_MODE_CBC` |
| `des-ede3-cbc` | ditto | `PKI_BC_DESEDE3+PKI_MODE_CBC` |
| `tdea-ecb` | Triple DES in ECB mode | `PKI_BC_TDEA+PKI_MODE_ECB` |
| `tdea` | ditto (ECB is default mode) | `PKI_BC_TDEA` |
| `aes128-cbc` | AES-128 in CBC mode | `PKI_BC_AES128+PKI_MODE_CBC` |
| `aes256-ctr` | AES-256 in Counter mode | `PKI_BC_AES256+PKI_MODE_CTR` |
| `aes192-gcm` | AES-192 in Galois/Counter mode | `PKI_BC_AES192+PKI_MODE_GCM` |

Punctuation and space characters and upper- and lower-case are ignored in the *szAlgAndMode* string, so 
`"tdea-cbc"`,
`"TDeA---cBc"`,
`"tdea cbc"`, and
`"TDEACBC"` are equivalent 
(as indeed is 
`"t*D$e^A c@b!C!!"`)

It is an error to use both the *szAlgAndMode* and *nOptions* parameters to specify the algorithm and mode.
The algorithm must be explicitly specified. There is no default algorithm. 
The default cipher mode is ECB mode, which is not recommended because of security issues. 
It is recommended to use either CBC or CTR mode with a IV value that is unique each time it is used with a given key.

### Padding

For the functions

[`CIPHER_EncryptBytes`](#CIPHER_EncryptBytes),
[`CIPHER_DecryptBytes`](#CIPHER_DecryptBytes),
[`CIPHER_EncryptHex`](#CIPHER_EncryptHex), 
[`CIPHER_DecryptHex`](#CIPHER_DecryptHex),
[`CIPHER_FileEncrypt`](#CIPHER_FileEncrypt) and
[`CIPHER_FileDecrypt`](#CIPHER_FileDecrypt),
you can specify padding as well as the algorithm and mode. 
The given padding will be added before encryption and removed after decryption according to the relevant rules.
If the padding is not given, default padding will be assumed which depends on the cipher mode. 

Valid padding names are:

| Value | Padding | Option |
| --- | --- | --- |
| `nopad[ding]` | No padding is added | `PKI_PAD_NOPAD` |
| `pkcs5[padding]` | The padding scheme described in PKCS#5/#7 [[PKCS5](#PKCS5)] | `PKI_PAD_PKCS5` |
| `oneandzeroes[padding]` | Pads with 0x80 followed by as many zero bytes necessary to fill the block | `PKI_PAD_1ZERO` |
| `ansix923[padding]` | The padding scheme described in ANSI X9.23 [[X9-23](#X9-23)] | `PKI_PAD_AX923` |
| `w3c[padding]` | The padding scheme described in W3C Recommendation for XML encryption [[XMLENC](#XMLENC)] | `PKI_PAD_W3C` |

So, for example, both `nopad` and `nopadding` are accepted, and so are `pkcs5` and `pkcs5padding`.

Remember that punctuation characters and case in the *szAlgModePad* string are ignored. 
The keywords must be in the correct order *algorithm-mode-padding*.
Some valid examples:

| szAlgModePad | Alternative Option value |
| --- | --- |
| `tdea/cbc/pkcs5` | `PKI_BC_TDEA+PKI_MODE_CBC+PKI_PAD_PKCS5` |
| `tdea/cbc/pkcs5padding` | `PKI_BC_TDEA+PKI_MODE_CBC+PKI_PAD_PKCS5` |
| `tdeacbcpkcs5` | `PKI_BC_TDEA+PKI_MODE_CBC+PKI_PAD_PKCS5` |
| `aes128-ecb-oneandzeroes` | `PKI_BC_AES128+PKI_MODE_ECB+PKI_PAD_1ZERO` |

[[Contents](#topofpage)] [[Index](#index)]

<a id="paddingschemes"></a>Padding schemes for block ciphers
------------------------------------------------------------

To perform encryption with a block cipher in ECB or CBC mode the length of the input to be encrypted 
*must* be an exact multiple of the block length *B* in bytes. 
For Triple DES the block length *B* is 8 bytes (64 bits) and for all AES variants it is 16 bytes (128 bits).
If the length of the data to be encrypted is not an exact multiple of *B*, it must be padded to make it so. 
After decrypting, the padding needs to be removed.

For other modes of encryption, such as "counter" mode (CTR) or OFB or CFB, padding is not required. In these cases
the ciphertext is always the same length as the plaintext, and a padding method is not applicable.

There are many, many conventions for padding. It is up to the sender and receiver of encrypted data to agree on the convention used.

The most popular is "PKCS5" padding, described in section 6.1.1 of [[PKCS5](#PKCS5)], 
which is the same as the padding method in section 6.3 of [[CMS](#CMS)], 
section 10.3 of [[PKCS7](#PKCS7)] 
and para 1.1 of [[RFC1423](#RFC1423)].

### PKCS5 Padding

If the block length is *B* then add *N* padding bytes of value *N* to make the input length 
up to the next exact multiple of *B*.
If the input length is already an exact multiple of *B* then add *B* bytes of value *B*. 
Thus padding of length *N* between one and *B* bytes is *always* added in an unambiguous manner. 
After decrypting, check that the last *N* bytes of the decrypted data all have value *N* with 
`1 < N ≤ B`.
If so, strip *N* bytes, otherwise throw a decryption error.

Examples of PKCS5 padding for block length *B* = 8:

```

3 bytes: FDFDFD           --> FDFDFD0505050505
7 bytes: FDFDFDFDFDFDFD   --> FDFDFDFDFDFDFD01
8 bytes: FDFDFDFDFDFDFDFD --> FDFDFDFDFDFDFDFD0808080808080808

```

### OneAndZeroes Padding

For "OneAndZeroes" Padding add a byte of value 0x80 followed by as many zero bytes as is necessary 
to fill the input to the next exact multiple of *B*.
Like PKCS5 padding, this method *always* adds padding of length between one and *B* bytes to the input before encryption. 
It is easily removed in an unambiguous manner after decryption.

The "OneAndZeroes" term comes from the fact that this method appends a 'one' bit to the input followed by as many 'zero' bits as is necessary.
The byte 0x80 is `10000000` in binary form. Note the spelling of "Zeroes", which is what everyone else seems to use.

Examples of OneAndZeroes padding for block length *B* = 8:

```

3 bytes: FDFDFD           --> FDFDFD8000000000
7 bytes: FDFDFDFDFDFDFD   --> FDFDFDFDFDFDFD80
8 bytes: FDFDFDFDFDFDFDFD --> FDFDFDFDFDFDFDFD8000000000000000

```

### ANSI X9.23 Padding

If *N* padding bytes are required (`1 < N ≤ B`) set the last byte as *N*
and all the preceding `N-1` padding bytes as zero.

Examples of AnsiX923 padding for block length *B* = 8:

```

3 bytes: FDFDFD           --> FDFDFD0000000005
7 bytes: FDFDFDFDFDFDFD   --> FDFDFDFDFDFDFD01
8 bytes: FDFDFDFDFDFDFDFD --> FDFDFDFDFDFDFDFD0000000000000008

```

### W3C Padding

As described in section 5.2.1 of the W3C Recommendation for XML encryption [[XMLENC](#XMLENC)].
If *N* padding bytes are required (`1 < N ≤ B`) set the last byte as *N*
and the preceding `N-1` padding bytes as arbitrary byte values. 

We include this method for completeness. It is similar to ISO10126 padding. 
This method is not recommended since only one padding byte is ever checked when decrypting
and this opens up security vulnerabilities. 
Note we actually use PKCS5 padding when encrypting, which is valid because the other padding bytes are 
specified as "arbitrary" and using *N* is just as arbitrary as any other value, isn't it? 

Examples of W3C padding for block length *B* = 8, where 'xy' is an arbitrary byte:

```

3 bytes: FDFDFD           --> FDFDFDxyxyxyxy05
7 bytes: FDFDFDFDFDFDFD   --> FDFDFDFDFDFDFD01
8 bytes: FDFDFDFDFDFDFDFD --> FDFDFDFDFDFDFDFDxyxyxyxyxyxyxy08

```

[[Contents](#topofpage)] [[Index](#index)]

<a id="blockciphersizes"></a>Valid key and block sizes for block cipher algorithms
----------------------------------------------------------------------------------

| Algorithm | Key size (bytes) | Block size (bytes) | IV size (bytes) | Valid ECB/CBC data lengths |
| --- | --- | --- | --- | --- |
| Triple DES | 24 | 8 | 8 | 8, 16, 24, 32, ..., 8i, ... bytes |
| AES-128 | 16 | 16 | 16 | 16, 32, 48, 64, ..., 16i, ... bytes |
| AES-192 | 24 | 16 | 16 | 16, 32, 48, 64, ..., 16i, ... bytes |
| AES-256 | 32 | 16 | 16 | 16, 32, 48, 64, ..., 16i, ... bytes |

[[Contents](#topofpage)] [[Index](#index)]

<a id="sigalgorithm"></a>Specifying the signature algorithm in a `SIG_` function
--------------------------------------------------------------------------------

The [signature functions](#sigfunctions) `SIG_Sign*` and `SIG_Verify*`
	allow the signature algorithm to be specified either by a *szAlgName* string or by using a flag in *nOptions*.

If the *szAlgName* contains a non-empty string, then its value is used and overrides any signature algorithm flag in
*nOptions*. 
If *szAlgName* is empty (`""`) then the `PKI_SIG_` flag in `nOptions` is used.

| szAlgName | Equivalent nOptions flag |
| --- | --- |
| `"sha1WithRSAEncryption"` or `"RSA-SHA1"` (default) | `PKI_SIG_RSA_SHA1` (0) |
| `"sha224WithRSAEncryption"` or `"RSA-SHA224"` | `PKI_SIG_RSA_SHA224` |
| `"sha256WithRSAEncryption"` or `"RSA-SHA256"` | `PKI_SIG_RSA_SHA256` |
| `"sha384WithRSAEncryption"` or `"RSA-SHA384"` | `PKI_SIG_RSA_SHA384` |
| `"sha512WithRSAEncryption"` or `"RSA-SHA512"` | `PKI_SIG_RSA_SHA512` |
| `"md5WithRSAEncryption"` or `"RSA-MD5"` | `PKI_SIG_RSA_MD5` |
| `"ecdsaWithSHA1"` or `"ECDSA-SHA1"` | `PKI_SIG_ECDSA_SHA1` |
| `"ecdsaWithSHA224"` or `"ECDSA-SHA224"` | `PKI_SIG_ECDSA_SHA224` |
| `"ecdsaWithSHA256"` or `"ECDSA-SHA256"` | `PKI_SIG_ECDSA_SHA256` |
| `"ecdsaWithSHA384"` or `"ECDSA-SHA384"` | `PKI_SIG_ECDSA_SHA384` |
| `"ecdsaWithSHA512"` or `"ECDSA-SHA512"` | `PKI_SIG_ECDSA_SHA512` |
| `"RSA-PSS-SHA1"` | `PKI_SIG_RSA_PSS_SHA1` |
| `"RSA-PSS-SHA224"` | `PKI_SIG_RSA_PSS_SHA224` |
| `"RSA-PSS-SHA256"` | `PKI_SIG_RSA_PSS_SHA256` |
| `"RSA-PSS-SHA384"` | `PKI_SIG_RSA_PSS_SHA384` |
| `"RSA-PSS-SHA512"` | `PKI_SIG_RSA_PSS_SHA512` |
| `"Ed25519"` | `PKI_SIG_ED25519` |
| `"Ed448"` | `PKI_SIG_ED448` |

Note that the combination `szAlgName=""` and `nOptions=0` results in the default  
`"sha1WithRSAEncryption"`.

[[Contents](#topofpage)] [[Index](#index)]

<a id="autackmsgs"></a>AUTACK messages and ISO/IEC 9796-1 signatures
--------------------------------------------------------------------

Specialist options have been added *[version 3.3]* to enable users to create digital signatures suitable for use
in an AUTACK message (see references [[SIEM99](#SIEM99)] and [[EDIFACT](#EDIFACT)]). 
This method uses a modified version of RSA (RSA2 in P1363 parlance) together with ISO 9796-1 formatting. 

To create such a digital signature, the user must carry out the following operations in sequence:

1. Create the message digest hash of the message to be signed using [`HASH_Bytes()`](#HASH_Bytes) 
function.
2. Encode (encapsulate) this message digest in ISO 9796-1 format using [`RSA_EncodeMsg()`](#RSA_EncodeMsg).
3. Sign, i.e. encrypt with the private RSA key, using [`RSA_RawPrivate()`](#RSA_RawPrivate).

Specific changes to enable this:

* Amended the
[`RSA_FromXMLString`](#RSA_FromXMLString)
function to allow the import of a restricted RSA private key from XML data consisting only of the 
`<Modulus>`, `<Exponent>` and `<D>` fields.
The resulting "internal" key string can be used to sign raw data but cannot be saved in a private key file.
We do this so we can reproduce the examples in [[EDIFACT](#EDIFACT)] (and discover an error in one of their examples!)
* Added a `PKI_EMSIG_ISO9796` option to the [`RSA_EncodeMsg`](#RSA_EncodeMsg) and
[`RSA_DecodeMsg`](#RSA_DecodeMsg)
functions to enable the user to encode and decode a message according to ISO/IEC 9796-1.
If this option is used, the message is encoded directly without the applicaton of any message digest algorithm.
It assumes that the RSA key length is exactly equal to the output length and that the most significant bit of the key modulus is set.
The user has to explicitly add the length of the key modulus in bits to the option. Yes, messy.
* Added an option to the [`RSA_RawPrivate`](#RSA_RawPrivate) and
[`RSA_RawPublic`](#RSA_RawPublic)
functions to sign and decrypt RSA signatures using the slightly modified method used in ISO/IEC 9796-1 and ANSI X9.31.
The user must explicitly add the option 0x6 or 0xC to nominate that the message representative *f*
is congruent to either 6 or 12, depending on which variant they are using.
Being congruent to 6 or 12 means that the last nibble of the message representative is either 0x6 or 0xC.
Autack requires the last nibble to be 0x6 and X9.31 requires it to be 0xC.

The method used in ISO 9796-1 has been shown to be insecure for signing plain text messages, i.e. signatures can be forged. 
However, it is still considered to be
secure when used to encode a *message digest*, as done in the Autack method.

For full sample code that shows how to sign and verify a message using Autack, 
see our [Autack](https://cryptosys.net/pki/autack.html "External link") page.

There are two steps:

1. Encode (pad) the message into a block the same size as the key: [ISO/IEC 9796-1 Formatting](#iso9796format).
2. Sign (encrypt) the block using RSA in a particular manner: [RSA2 Signing](#rsa2sign).

### <a id="iso9796format"></a>ISO/IEC 9796-1 Formatting

ISO/IEC 9796-1 formatting takes a message of limited length and "weaves" it into a padded block the same size in bytes as the RSA key modulus.
It allows message recovery, but is more secure if used to format a message digest of the original message.
It requires knowledge of the exact size of the key modulus in bits.
The encoded message will always be one bit shorter than the key length, as far as significant bits are concerned.
However, the returned byte array will always be the same size as the key *in bytes*; i.e., `ceil(keybits/8)` bytes.
For an extreme case like a 1025-bit key, it will return a byte array of 129 bytes with the most significant byte zero.

We use the [`RSA_EncodeMsg`](#RSA_EncodeMsg) function and pass an option parameter 
consisting of the `PKI_EMSIG_ISO9796`
flag plus the actual size of the key in bits. Do not use any other flags.
To decode and recover the message, use the [`RSA_DecodeMsg`](#RSA_DecodeMsg) function
in the same manner. In VB6/VBA:

```

' Encapsulate hash digest in ISO9796-1 encoding
'  -- we need a block of the same length as the key in bytes
nKeyBits = RSA_KeyBits(strPrivateKey)
Debug.Print "RSA key length=" & nKeyBits & " bits"
blen = RSA_KeyBytes(strPrivateKey)
ReDim abBlock(blen - 1)
' plus pass the exact key length in bits as part of the option parameter...
r = RSA_EncodeMsg(abBlock(0), blen, abDigest(0), dlen, PKI_EMSIG_ISO9796 + nKeyBits)
Debug.Print "RSA_EncodeMsg returns " & r & " (expecting >=0)"
If (r < 0) Then Exit Function
Debug.Print "Encoded block ready to sign=" & vbCrLf & cnvHexStrFromBytes(abBlock)

```

In C# and `VB.NET`/VB20xx, use the special `Rsa.EncodeMsgIso9796` and `Rsa.DecodeMsgIso9796` methods. 

```

keyStr = Rsa.FromXMLString(xmlKey, false);
keyBits = Rsa.KeyBits(keyStr);
Console.WriteLine("Private key is {0} bits long", keyBits);
// Compute message digest of data
hexDigest = Hash.HexFromString(msgStr, HashAlgorithm.Sha1);
Console.WriteLine("Message-to-encode=Digest={0}", hexDigest);
// Convert digest to byte array
msg = Cnv.FromHex(hexDigest);
// Encode digest using ISO-9796-1
b = Rsa.EncodeMsgIso9796(msg, keyBits);
Debug.Assert(b.Length > 0, "Failed to Encode for ISO9796-1");

```

### <a id="rsa2sign"></a>RSA2 Signing

The RSA2 method of signing is described in ANSI X9.31 and IEEE P1363. It is also known as the Rabin method.
We only offer the variant for an odd exponent. 
The method saves one bit in output compared to the PKCS#1v.15 method - even a whole byte if the key is say, 1025 bits. Yes!

 
For an input message representative, *f*, with private key (*n,d*) and `f < n`, 
the output signature, *s*, is the minimum of
`fd mod n` and `n - (fd mod n)`.
The last nibble of the message representative must be either 0x6 or 0xC (12) depending on the scheme,
i.e. `f ≡ 6 (mod 16)` or `f ≡ 12 (mod 16)`.

```

' Sign block with RSA private key to create signature
' -- use special ISO9796/X9.31/P1363 RSA2 method with magic value 0x6
r = RSA_RawPrivate(abBlock(0), blen, strPrivateKey, &H6)
Debug.Print "RSA_RawPrivate returns " & r & " (expecting 0)"
If (r <> 0) Then Exit Function
' Convert to hex encoding
strHexSig = cnvHexStrFromBytes(abBlock)

```

In C# and `VB.NET`/VB20xx, use the `Rsa.RawPrivate` and `Rsa.RawPublic`
methods respectively to sign and verify the encoded block. Use the overload with
the specialist option to pass the value of the "magic nibble".

```

// Sign block with RSA private key
// -- use special RSA2 method with magic nibble value 6
b = Rsa.RawPrivate(b, keyStr, 0x6);
// Convert to hex encoding
s = Cnv.ToHex(b);

```

[[Contents](#topofpage)] [[Index](#index)]

<a id="cmstypes"></a>CMS Content Types
--------------------------------------

Cryptographic Message Syntax (CMS) is a syntax used to digitally sign, digest, authenticate, or encrypt
arbitrary message content. CMS is a stricter subset of PKCS#7.
There are several CMS content types but S/MIME currently only uses four of them, namely
Data, SignedData, EnvelopedData, and CompressedData content types. 
This Toolkit provides the means to create digitally-signed `SignedData`, 
encrypted `EnvelopedData` and `CompressedData` objects* according to 
the CMS specification [[CMS](#CMS)] and some of its more recent updates.

* **Pedantic note:** Strictly speaking, the objects produced are 
CMS `SignedData` or `EnvelopedData` objects
wrapped in a CMS `ContentInfo` object.

### <a id="signeddata"></a>CMS SignedData objects

A SignedData object is a digitally-signed container for arbitrary message content. You can create
a SignedData object using one of the
[`CMS_MakeSigData`](#CMS_MakeSigData),
[`CMS_MakeSigDataFromString`](#CMS_MakeSigDataFromString),
[`CMS_MakeSigDataFromSigValue`](#CMS_MakeSigDataFromSigValue), or
[`CMS_MakeDetachedSig`](#CMS_MakeDetachedSig)
 functions.

Some options:
* The original message content (known as `eContent`) may be included or not (the latter case
is known as a "detached signature").
* One person may sign it, or there may be multiple signers.
* The person signing may or may not include their X.509 certificate for the recipient to use to verify the signature.
If it is not included, the recipient has to obtain a copy of the signer's certificate by other means.
* The entire certificate chain for the signer (or multiple signers) can also be included, as could any other certificate
the creator feels like including.
* At one extreme, the SignedData object can just consist of a collection of certificates with no signature and no
	signed message content. These are known as PKCS#7 *certficate chain files* or in S/MIME terminology 
	as *degenerate "certs-only" objects*. 
	This format is commonly used to distribute X.509 certificates, usually with the .p7c or .p7b
	filename extension. Some people sneakily use the .cer extension for these types of files as well, even though that extension
	is usually used only for single X.509 certificates.

To verify that the message content was indeed signed by the signer requires the recipient to
do the following:

1. Obtain a copy of the signer's X.509 certificate, unless this is already included in the SignedData,
	and verify independently that this certificate is valid.
2. Decrypt the signature in the SignedData using the public key inside the signer's certificate.
3. Verify that the message digest of the eContent matches the message digest included in the SignedData.

The function
[`CMS_VerifySigData`](#CMS_VerifySigData)
carries out steps 2 and 3 directly with options for the user to pass the signer's certificate details if they are not already included
and also to pass the message digest of the eContent for detached signatures.

The function
[`CMS_GetSigDataDigest`](#CMS_GetSigDataDigest)
will extract the message digest, if possible, to enable the user to perform their own separate comparison
with an independently-computed message digest of the eContent. Note that being able to retrieve the message digest
with this function implicitly verifies that the purported signer really did use their private key to sign the object. 

However,
unlike the `CMS_VerifySigData` function, success with this function does not necessarily mean that the signer actually signed
the eContent itself. Furthermore, if the signer used the DSA or RSA-PSS signature algorithms and did not include message attributes,
then you cannot directly extract the message digest of the eContent.

To extract just the certificates themselves from a SignedData object, use the 
[`X509_GetCertFromP7Chain`](#X509_GetCertFromP7Chain)
function. This will work for all types of SignedData objects, not just the "certs-only" type.

#### <a id="additionalsecurityattributes"></a>Additional security attributes *[New in v12.4]*

Include the option `PKI_CMS_ADD_SIGNINGCERT` (`Cms.SigDataOptions.AddSigningCertificate`) 
to add an *ESS Signing Certificate Attribute* to the signed attributes.
The signing certificate attribute is designed to prevent simple substitution and re-issue attacks 
by cryptographically linking the certificate used to create the signature with the signature itself.
This is required for B-level conformance with CAdES-BES [[CADES](#CADES)], which in turn refers to 
ESS [[RFC2634](#RFC2634)] and [[RFC5035](#RFC5035)].

Include the option `PKI_CMS_ADD_ALGPROTECT`  (`Cms.SigDataOptions.	AddAlgProtection`) 
to add an *Algorithm Protection Attribute* to the signed attributes.
This is in accordance with  [[RFC6211](#RFC6211)].
If a CMS validator supports this attribute (which this Toolkit now does - see [`CMS_VerifySigData`](#CMS_VerifySigData)), 
then additional checks are made to protect against signature and message digest algorithm substitution attacks.

### <a id="envelopeddata"></a>CMS EnvelopedData objects

An EnvelopedData object contains encrypted content for one or more recipients. You can create
an EnvelopedData object using one of the
[`CMS_MakeEnvData`](#CMS_MakeEnvData),
[`CMS_MakeEnvDataFromString`](#CMS_MakeEnvDataFromString), or
[`CMS_MakeEnvDataFromBytes`](#CMS_MakeEnvDataFromBytes)
 functions.

The content is encrypted with a single, randomly-generated content encryption key (CEK). 
Each recipient is provided with this CEK encrypted specifically for them using one of four key management techniques.
The combination of the encrypted content and one encrypted CEK is called a *digital envelope* for that recipient.
An EnvelopedData object consists of a set of *RecipientInfo* types, one for each recipient, and the encrypted content.

There are four key management techniques.

1. key transport, represented in the `KeyTransRecipientInfo` (ktri) type
2. key agreement, represented in the `KeyAgreeRecipientInfo` (kari) type
3. symmetric key-encryption keys, represented in the `KEKRecipientInfo` (kekri) type
4. passwords, represented in the `PasswordRecipientinfo` (pwri) type

As of *[v20.6]*, all four key management techniques are supported. ktri has always been supported. Support for kari was added in *[v20.5]*,
and support for kekri and pwri added in *[v20.6]*.

**key transport (ktri)**. The CEK is encrypted in the recipient's public key. 
We support the RSAES-PKCS1-v1_5 and the RSAES-OAEP encryption schemes.
  
*Options:* RSAES-OAEP can specify the hash algorithm to be used and the hash algorithm to be used with the MGF.

**key agreement (kari)**. The recipient's public key and the sender's private key are used to generate a pairwise symmetric key, which is used to encrypt the CEK.
All elliptic curve public keys we support can be used in this mode. A key derivation function (KDF) and a key wrap algorithm must be specified.
  
*Options:* Supported KDFs are the ANSI-X9.63-KDF key derivation function and the HMAC-based Key Derivation Function (HKDF) from RFC 5869.
Additonal user key material (UKM) may be provided. Triple DES key wrap and the AES key wrap algorithms are supported.

**symmetric key-encryption keys (kekri)**. The CEK is encrypted in a previously distributed symmetric key-encryption key.
  
*Options:* Triple DES key wrap and the AES key wrap algorithms are supported. Restricted to one recipient per document.

**passwords (pwri)**. The CEK is encrypted in a key-encryption key derived from a password as described in [[RFC3211](#RFC3211)].
The PWRI-KEK key wrap algorithm specified in section 2.3 of RFC3211 is used together with the PBKDF2 key derivation algorithm.
  
*Options:* The hash algorithm and iteration count used with PBKDF2 can be specified. Restricted to one recipient per document.

Summary of required and optional parameters for each type (†=required)

| Parameter | ktri | kari | kekri | pwri |
| --- | --- | --- | --- | --- |
| certList | †cert[s] | †cert[s] | †`"@kekri"` | †`"@pwri"` |
| cipherAlg | ✓ | ✓ | ✓ | ✓ |
| keyEncrAlg | ✓ | N/A | N/A | N/A |
| hashAlg | ✓ | ✓ | N/A | ✓ |
| advOpts | ✓ | ✓ | ✓ | ✓ |
| kdfAlg | N/A | ✓ | N/A | N/A |
| keyWrapAlg | N/A | ✓ | ✓ | N/A |
| keyString | N/A | ukm | †kekstr | †password |
| count | N/A | N/A | N/A | iterCount |

### <a id="authenvelopeddata"></a>CMS AuthEnvelopedData objects

*[New in v20.6]*
If an authenticated encryption algorithm is used to encrypt the content, then an AuthEnvelopedData object is created as per [[RFC5083](#RFC5083)]. 
This is similar to an EnvelopedData object but contains an additional authentication tag field (a.k.a. MessageAuthenticationCode, mac). 
We provide support for AuthEnvelopedData using the AES-GCM and *[New in v22.0]* ChaCha20Poly1305 algorithms and all the key management techniques decribed above.

The standard tag length for AES-GCM is 16 bytes, and a truncated tag of 12, 13, 14, or 15 bytes is permitted. 
For some reason the default length in RFC5083 is given as 12 bytes but we always provide a 16-byte tag.

[[Contents](#topofpage)] [[Index](#index)]

<a id="usinginmime"></a>Using in MIME-conformant email messages
---------------------------------------------------------------

This toolkit produces enveloped-data and signed-data CMS objects which can be used in S/MIME v3 messages. 
To send the output as an email message you first need to wrap it in a MIME body,
and to decrypt or verify an incoming message you need to extract the CMS object first.

Use the  [`SMIME_Wrap`](#SMIME_Wrap) function or
`[Smime.Wrap](#M_Smime_Wrap)` method
to create an S/MIME file from binary CMS signed-data, enveloped-data and compressed-data objects,
and the [`SMIME_Extract`](#SMIME_Extract) function or
`[Smime.Extract](#M_Smime_Extract)` method
to extract the body from an S/MIME file.

### Sending an enveloped-data object

The output from the [`CMS_MakeEnvData`](#CMS_MakeEnvData)
 or `CMS_MakeEnvDataFromString` function
is a CMS object. This CMS object needs to be inserted into an `application/pkcs7-mime` MIME entity
before being sent as an email message.

The CMS object is sent as an attachment to the email, usually with the name `smime.p7m`.
If your email program allows you to tailor the headers, you should identify the Content-Type as 
`application/pkcs7-mime; smime-type=enveloped-data`. 
Most email programs convert the binary CMS object file into base64 encoding automatically.
If not, you can use the `PKI_CMS_FORMAT_BASE64` option to generate the output directly 
in base64 encoding.

Ann creates a message for Ben using the default option:

```

nRet = CMS_MakeEnvDataFromString("smime.p7m", _
    "Be in bar at 7 pm wearing a red rose", "ben.cer", "", 0, 0);

```

The output file `smime.p7m` will be in binary BER-encoded format. 
To send as an S/MIME email, you attach this file to your email message and you need to add the following headers:-

```

Date: Mon, 23 Feb 2004 12:00:52 +1100
From: alice@example.com
To: ben@example.com
Subject: Secret message
MIME-Version: 1.0
Content-Type: application/pkcs7-mime;
    smime-type=enveloped-data; id="smime.p7m"
Content-Transfer-Encoding: base64
Content-Description: attachment;filename=smime.p7m

MIAGCSqGSIb3DQEHA6CAMIACAQAxgZMwgZACAQAwOjA0MQswCQYDVQQGEwJBVTEV
...

```

When Bob receives the email, he can either:-

1. Rely on his email program correctly identifying the enveloped-data pkcs7-mime message and 
using his certificate and private key he previously loaded into the Windows certificate store to decrypt it; or
2. Save the attachment from the email to a file on his hard drive and decrypt it using the toolkit
[`CMS_ReadEnvData`](#CMS_ReadEnvData) function.

Identifying the Content-Type as `application/pkcs7-mime` and `enveloped-data` 
should ensure that the receiving email
program correctly identifies the file as an encrypted email and treats it accordingly. This is optional,
and you may find it more convenient to agree with your sending parties not to do this so you can just save the attached data file directly 
without getting involved in the "security" hoops that programs like Outlook Express will put you through.

If you can't save the attachment file directly from your email program, remember that email files are just
simple text files (even though they may have a `.EML` extension) and can be edited using a simple text editor
like NotePad. Open the email in your favorite text editor and do a cut-and-paste of the attachment data to another file. 

### Sending an signed-data object

There are two formats for signed messages for S/MIME:

1. S/MIME application/pkcs7-mime signed message
2. S/MIME multipart/signed message

The first format is simpler for our purposes. It consists of a signed-data CMS object which includes the
signed content as created by the default 
[`CMS_MakeSigData`](#CMS_MakeSigData) or `CMS_MakeSigDataFromString`
functions.
The MIME headers are similar to the enveloped-data example above:-

```

MIME-Version: 1.0
To: ben@example.com
From: ann@example.com
Subject: Signed message
Date: Mon, 23 Feb 2004 12:00:52 +1100
Content-Type: application/pkcs7-mime; smime-type=signed-data;
    name=smime.p7m
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=smime.p7m

MIIDmwYJKoZIhvcNAQcCoIIDjDCCA4gCAQExCTAHBgUrDgMCGjAtBgkqhkiG9w0BBwGgIA
QeDQpUaGlzIGlzIHNvbWUgc2FtcGxlIGNvbnRlbnQuoIIC4jCCAt4wggKdoAMCAQICAgDI
...

```

To read, just save the attachment to your hard drive and read the file with 
[`CMS_ReadSigData`](#CMS_ReadSigData) or `CMS_ReadSigDataToString`.

The second format, S/MIME multipart/signed, includes the actual content in the body of the email message
and attaches a "detached signature" signed-data object identified as 
`Content-Type: application/pkcs7-signature; name=smime.p7s`
in the MIME part header. This has the advantage that the signed content can be read directly in the email message,
but you need a more sophisticated email program to create the final message.
The detached signature CMS object can be created using the 
[`CMS_MakeDetachedSig`](#CMS_MakeDetachedSig) function.

A typical multipart/signed message is:

```

MIME-Version: 1.0
To: ben@example.com
From: ann@example.com
Subject: Multi-part signed message
Date: Mon, 23 Feb 2004 12:00:52 +1100
Content-Type: multipart/signed;
    micalg=SHA1;
    boundary="----=_NextBoundry";
    protocol="application/pkcs7-signature"

This is a multi-part message in MIME format.

------=_NextBoundry

This is some sample content.
------=_NextBoundry
Content-Type: application/pkcs7-signature; name=smime.p7s
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=smime.p7s

MIIDeQYJKoZIhvcNAQcCoIIDajCCA2YCAQExCTAHBgUrDgMCGjALBgkqhkiG9w0BBwGggg
LiMIIC3jCCAp2gAwIBAgICAMgwCQYHKoZIzjgEAzASMRAwDgYDVQQDEwdDYXJsRFNTMB4X
...

------=_NextBoundry--

```

You are strongly recommended to use quoted-printable encoding for the content part of the 
message to prevent the signed data being changed during transmission.

### More information on S/MIME

For more details on how to insert your CMS objects into MIME bodies (honest, that's the term they use), please
refer to *S/MIME Version 3 Message Specification* [[SMIME-MSG]](#SMIME-MSG) and
*Examples of S/MIME Messages* [[SMIME-EX]](#SMIME-EX). Stallings also covers
the topic well in *Cryptography and Network Security* [[STAL]](#STAL).

[[Contents](#topofpage)] [[Index](#index)]

<a id="xmldocs"></a>Using output in XML documents
-------------------------------------------------

You can create most of the cryptographic elements required in the 
[[XML-DSIG](#XMLDSIG)] and [[XML-ENC](#XMLENC)] specifications to insert into XML documents. 
These XML values should be encoded in base64 encoding.

Use 
[`CNV_B64StrFromBytes`](#CNV_B64StrFromBytes) or
[`Cnv.ToBase64`](#M_Cnv_ToBase64_Byte)
to convert byte arrays into base64 encoding.

Here is a selection of some elements you can create.

### `SignatureValue` element

Use 
[`Sig.SignData`](#M_Sig_SignData)
or 
[`Sig.SignFile`](#M_Sig_SignFile).

Alternatively, use
[`Rsa.EncodeMsgForSignature`](#M_Rsa_EncodeMsgForSignature) followed by
[`Rsa.RawPrivate`](#M_Rsa_RawPrivate_ByteString)
then
[`Cnv.ToBase64`](#M_Cnv_ToBase64_Byte).

### `DigestValue` element

Use 
[`Hash.BytesFromBytes`](#M_Hash_BytesFromBytes)
or
[`Hash.BytesFromFile`](#M_Hash_BytesFromFile)
then
[`Cnv.ToBase64`](#M_Cnv_ToBase64_Byte).

### `X509Certificate` element

Use
[`X509.ReadStringFromFile`](#M_X509_ReadStringFromFile).

### `X509IssuerSerial` element

Use 
[`X509.QueryCert`](#M_X509_QueryCert)	with query `"serialNumber"` and 
`[X509.OutputOpts](#T_X509_OutputOpts).Decimal`.

### `X509SubjectName` element

Use 
[`X509.QueryCert`](#M_X509_QueryCert)	with query `"subjectName"` and 
`[X509.OutputOpts](#T_X509_OutputOpts).Ldap`.

### `RSAKeyValue` element

Use 
[`Rsa.KeyValue`](#M_Rsa_KeyValue) or
[`Rsa.ToXMLString`](#M_Rsa_ToXMLString_StringRsa_XmlOptions).

### `RSAKeyPair` element

Use 
[`Rsa.ToXMLString`](#M_Rsa_ToXMLString_StringRsa_XmlOptions).

### `CipherValue` element

**xmlenc#rsa-1_5:** 
Use 
[`Rsa.EncodeMsgForEncryption`](#M_Rsa_EncodeMsgForEncryption)
with `[Rsa.EME](#T_Rsa_EME).PKCSv1_5` option
followed by
[`Rsa.RawPublic`](#M_Rsa_RawPublic_ByteString)
then
[`Cnv.ToBase64`](#M_Cnv_ToBase64_Byte)

**xmlenc#rsa-oaep-mgf1p:** 
As for `xmlenc#rsa-1_5` except use 
`[Rsa.EME](#T_Rsa_EME).OAEP` option.

**xmlenc#tripledes-cbc:** Use
[`Cipher.Encrypt`](#M_Cipher_Encrypt_ByteByteByteCipherAlgorithmModePaddingCipher_Opts)
with options
`[CipherAlgorithm](#T_CipherAlgorithm).Tdea`,
`[Mode](#T_Mode).CBC` and
`[padding](#T_Padding).Pkcs5`,
then
[`Cnv.ToBase64`](#M_Cnv_ToBase64_Byte).

**xmlenc#aes128-cbc:** 
As for `xmlenc#tripledes-cbc` except use 
`[CipherAlgorithm](#T_CipherAlgorithm).Aes128` option.

**xmlenc#aes192-cbc:** 
As for `xmlenc#tripledes-cbc` except use 
`[CipherAlgorithm](#T_CipherAlgorithm).Aes192` option.

**xmlenc#aes256-cbc:** 
As for `xmlenc#tripledes-cbc` except use 
`[CipherAlgorithm](#T_CipherAlgorithm).Aes256` option.

[[Contents](#topofpage)] [[Index](#index)]

<a id="base64url"></a>Base64url encoding and JSON Web Signatures (JWS)
----------------------------------------------------------------------

Use the optional `PKI_ENCODE_BASE64URL` option when creating a signature with 
[`SIG_SignData`](#SIG_SignData) or [`Sig.SignData`](#M_Sig_SignData)
to output the signature value in base64url encoding suitable for inserting in a JSON Web Signature.

**Base64url** encoding is defined in [[RFC7515](#RFC7515)] to use the URL- and filename-safe
character set in section 5 of [[RFC4648](#RFC4648)] with all trailing "=" characters omitted.

The base64url character set is identical to base64 except "+" (plus sign, U+002B) is replaced by "-" (hyphen-minus, U+002D), and "/" (slash, U+002F) by "_" (underscore, U+005F).

For example, the byte array represented in hexadecimal by "FEDCBAF8765432" is represented by `"/ty6+HZUMg=="` in base64 and `"_ty6-HZUMg"` in base64url.

[[Contents](#topofpage)] [[Index](#index)]

<a id="rawrsa"></a>Raw RSA Techniques
-------------------------------------

The original intention of this Toolkit was to provide a set of primitives to carry out S/MIME operations
using relatively high-level functions.
However, we get so many questions about using the "raw" RSA functions that
we've added this section on techniques.

The functions [RSA_RawPublic](#RSA_RawPublic) and [RSA_RawPrivate](#RSA_RawPrivate)
just carry out the basic RSA encryption or decryption operation on a "raw" block of data.
The block *must* be exactly the same length in bytes as the length of the RSA key modulus;
it must obey certain mathematical properties (in practice, make sure the first byte is zero);
and it should be "padded" in a certain way to improve security and make it easier to 
pass to other systems 
(the built-in cryptographic functions in .NET hide this part of the process from you).

### Encrypting and signing with RSA

Encryption and signing use the same RSA operations:

* To encrypt, ciphertextblock = RSA(plaintextblock, public-key)
* To decrypt, plaintextblock = RSA(ciphertextblock, private-key)
* To sign, signatureblock = RSA(messageblock, private-key)
* To verify, messageblock' = RSA(signatureblock, public-key).

In practice, there are rules  to pad the input data before applying the RSA transformation.

Use the function [RSA_EncodeMsg](#RSA_EncodeMsg) to encode or "pad" the message data you want to
encrypt or sign. This uses the rules in [[PKCS#1](#PKCS1)]. 
Then use the appropriate `RSA_Raw` function with the public or private RSA key.

To encrypt some data:
use 
[`Rsa.EncodeMsgForEncryption`](#M_Rsa_EncodeMsgForEncryption)
with either the `[Rsa.EME](#T_Rsa_EME).PKCSv1_5` option
or the `[Rsa.EME](#T_Rsa_EME).OAEP` option,
followed by
[`Rsa.RawPublic`](#M_Rsa_RawPublic_ByteString).
The length of the data you can encrypt is limited by the size of the RSA key modulus. This is typically used to encrypt a session key.
The data is padded with random bytes before encryption, so the result is *always* different.

To sign some data: use 
[`Rsa.EncodeMsgForSignature`](#M_Rsa_EncodeMsgForSignature) followed by
[`Rsa.RawPrivate`](#M_Rsa_RawPrivate_ByteString).
The length of the data to be signed is effectively unlimited (well, with some very large limit) because EncodeMsg creates a message digest of the
data. If your data-to-be-signed is short enough, it is possible to avoid the EncodeMsg step 
and construct a block to be signed containing the original data (*Hint:* make sure the first byte is zero).

### More convenient and secure alternatives

Use the functions [`RSA_Encrypt`](#RSA_Encrypt) and [`RSA_Decrypt`](#RSA_Decrypt) to carry out RSA encryption and decryption more conveniently and securely in one step.
In .NET use the [`Rsa.Encrypt`](#M_Rsa_Encrypt) and [`Rsa.Decrypt`](#M_Rsa_Decrypt) methods.
To sign data in one step, use [`SIG_SignData`](#SIG_SignData) 
([`Sig.SignData Method`](#M_Sig_SignData)).
To verify a signature, use [`SIG_VerifyData`](#SIG_VerifyData) 
([`Sig.VerifyData Method`](#M_Sig_VerifyData)).

[[Contents](#topofpage)] [[Index](#index)]

<a id="rsaschemes"></a>RSA signature and encryption schemes: RSA-PSS and RSA-OAEP
---------------------------------------------------------------------------------

There are two RSA signature schemes specified in [[PKCS1](#PKCS1)]: RSASSA-PKCS1-v1_5 and RSASSA-PSS  (RSASSA = *RSA Signature Scheme with Appendix*).
*RSASSA-PSS* is a probabilistic signature scheme (PSS) with appendix. 
A signature scheme with appendix requires the message itself to verify the signature (i.e. the message is not recoverable from the signature).

There are also two RSA encryption schemes: RSAES-PKCS-v1_5 and RSAES-OAEP (*Optimal Asymmetric Encryption Padding*). Both use random seeds (and so produce a different ciphertext value each time), 
but RSA-OAEP is more robust and is the recommended alternative. 

The PKCS-V1_5 schemes are "self contained": the signature values and ciphertext values contain all the information needed to verify or decipher.
In contrast, both the RSA-PSS and RSA-OAEP schemes require parameters which need to be provided separately. 
Both require a hash function to be specified and both use a mask generation function (MGF).
There is currently only one MGF specified, called `MGF1`. 
This in turn uses a hash function (the "MGF hash function") which may be different from the scheme hash function. 
More details [below](#parametersrsapssoaep).

Incidentally, the terms "function" and "algorithm" are used interchangeably here. The term "algorithm" was used in the early PKCS#1 specifications
(and is reflected in the ASN.1 type names), and "function" is used in the more recent ones. 

### Differences between signature schemes RSASSA-PKCS-v1_5 and RSASSA-PSS

The signature schemes RSASSA-PKCS-v1_5 ("PKCSV1_5") and RSASSA-PSS ("PSS") have differences. 

* PKCSV1_5 is deterministic. The same message and key will produce an identical signature value each time.
PSS is randomized and will produce a different signature value each time (unless you use a zero-length salt).
* A PKCSV1_5 signature is complete in itself. Once decrypted using the private key, you can detect the hash function used to create it
	and extract the message digest value.
A PSS signature has separate parameters (see below) which need to be known prior to verifying a signature. 
These are included in X.509 certificates and CMS signed-data objects,
but need to be communicated separately for an isolated signature value.
* You can extract the message digest value from a PKCSV1_5 signature. You cannot extract it from a PSS signature; you can only verify against a known digest value.
* PSS has a security proof and is more robust in theory than PKCSV1_5. Nevertheless PKCSV1_5 has no known security weaknesses at this time.
* PSS had patent issues until recently (the last one expired in 2010) and is less widely adopted. PKCSV1_5 has been widely used since the 1990s.

### RSASSA-PSS parameters

* hash algorithm/function. The default is SHA-1 [minimum recommended SHA-256].
* mask generation function (MGF). Currently always MGF1.
* salt length. The default value is 20 but the convention is to use *hLen*, the length of the output of the hash function in bytes.
	A salt length of zero is permitted and will result in a deterministic signature value. The actual salt length used can be determined from the signature value.
* trailer field, used in the encoding operation. The default trailer field is the byte 0xbc. This is the only option available in this Toolkit.

The default parameters for RSASSA-PSS are:

> ```
> hashAlgorithm       sha1,
> maskGenAlgorithm    mgf1SHA1 (the function MGF1 with SHA-1)
> saltLength          20,
> trailerField        trailerFieldBC (the byte 0xbc)
> 
> ```

It is recommended that the MGF hash function be the same as the scheme hash algorithm/function, and that the salt length be `hLen`, the length of the output of the hash function.

### Differences between encryption schemes RSAES-PKCS-v1_5 vs RSAES-OAEP

* RSAES-OAEP has a security proof and is the recommended scheme in new implementations. 
The older RSAES-PKCS-v1_5 scheme has some known vulnerabilities (easily avoided), and is still widely used.
* Both use random seeds and so produce a different ciphertext each time for a given plaintext and key.
* A PKCSV1_5 ciphertext is complete in itself. Once decrypted using the private key, you can extract the plaintext directly.
* An RSA-OAEP ciphertext requires separate parameters to decrypt it as well as the key. 
	These are included in a CMS enveloped-data object but need to be provided separately for an isolated ciphertext value.

### RSAES-OAEP parameters

* hash algorithm/function. The default is SHA-1 [minimum recommended SHA-256].
* mask generation function (MGF). Currently always MGF1.
* pSourceAlgorithm. The source or value of the label L used in the OEAP encoding operation. The default is the empty string `""`. 
This is the only option available in this Toolkit.

The default parameters for RSASSA-OAEP are:

> ```
> hashAlgorithm       sha1,
> maskGenAlgorithm    mgf1SHA1 (the function MGF1 with SHA-1)
> pSourceAlgorithm    pSpecifiedEmpty (label L is an empty string)
> 
> ```

It is recommended that the MGF hash function be the same as the scheme hash algorithm/function.

### <a id="parametersrsapssoaep"></a>Parameters for RSA-PSS and RSA-OAEP available in this Toolkit

The mask generation function (MGF) is always MGF1 from section B.2.1 of PKCS1 (currently there is no other MGF function defined).
Note that the scheme hash function and the MGF hash function can be different.
In this Toolkit, the default hash function is SHA-1. 
You can specify a different hash function using the *nOptions* argument. 
If you do so then the MGF1 hash algorithm will also be same hash function (this is recommended practice). 
Add the `PKI_MGF_MGF1SHA1` option to force the MGF hash function to be SHA-1 (which, strictly speaking, is still the default).
You cannot set any other combinations of scheme and MGF1 hash functions in this Toolkit.
The default salt length for RSA-PSS is `hLen`, the length of the output of the hash function in bytes. 
You can change the salt length when creating a signature using the `PKI_PSS_SALTLEN_*` options.
In this Toolkit, the "trailer byte" for RSA-PSS is always 0xbc and the label L for RSA-OAEP is always the empty string; these cannot be changed.

Note also that there are physical limitations in the length of message digest used in the MGF function with RSA-PSS and RSA-OAEP: you cannot, for instance, 
use the SHA-512 MGF digest function with a 1024-bit RSA key (the digest is too long).

[[Contents](#topofpage)] [[Index](#index)]

<a id="rsakem"></a>RSA-KEM
--------------------------

*[New in v23.0]*
The RSA Key Encapsulation Mechanism (RSA-KEM) Algorithm is a one-pass (store-and-forward) 
cryptographic mechanism for an originator to securely send keying material to a recipient using the recipient's RSA public key.
("KEM" stands for "key encapsulation mechanism".)

Using the RSA-KEM Algorithm with the Cryptographic Message Syntax (CMS) is described in [[RFC5990bis](#RFC5990bis)].
It makes use of the KEMRecipientInfo structure as specified in [[RFC9629](#RFC9629)] 
as part of a CMS OtherRecipientInfo ("ori") type.

RSA-KEM provides higher security assurance than traditional uses of the RSA algorithm (e.g. RSAES-PKCS1-v1_5) because 
the input to the underlying RSA operation is a random integer without any structure that can be exploited,
and the input is independent of the keying data so the result of the RSA decryption operation is not directly available to an adversary.

This Toolkit supports RSA-KEM using KEMRecipientInfo with key derivation functions KDF2, KDF3 and HKDF; 
key-wrap algorithms aes*-wrap (where * is 128, 192 or 256) and hash functions SHA-* (where * is 256, 384 or 512).
To use, call [CMS_MakeEnvData](#CMS_MakeEnvData) with the option flag `PKI_CMS_RSA_KEM`.
The default options are KDF3 with aes128-wrap and SHA-256.

Triple-DES and SHA-1 are *not* supported for this implementation of RSA-KEM.

[[Contents](#topofpage)] [[Index](#index)]

<a id="ecdh"></a>Elliptic curve Diffie-Hellman (ECDH)
-----------------------------------------------------

 *[New in v20.0]*
Support is provided for Elliptic Curve Diffie-Hellman (ECDH) operations using the [ECC_DHSharedSecret](#ECC_DHSharedSecret) and 
.NET [`Ecc.DHSharedSecret Method`](#M_Ecc_DHSharedSecret).

These functions enable you to compute the *shared secret* given your own private EC key and the other party's public EC key.
Note this shared secret (often denoted *ZZ* or *Z*) is usually not used directly itself, but is passed to another function such as a key derivation function, perhaps with 
other agreed parameters. These subsequent operations are out of scope here. 

Note also that there are *two* ways to compute the shared secret using the NIST/SEC curves. One way using the *cofactor* and one without.
The former is referred to as "ECC Cofactor Diffie-Hellman (ECC CDH)" in [[SP800-56A](#SP800-56A)] and "ECSVDP-DHC" in [[IEEE1363](#IEEE1363)], 
and the latter as "ECSVDP-DH" in [[IEEE1363](#IEEE1363)] and [[RFC5349](#RFC5349)].
**BUT** all the NIST/SEC curves in this toolkit have a cofactor of one, so you get the same result with either calculation.

There is only one accepted way to compute the shared secret using the safe curves X25519 and X448 - see [[RFC7748](#RFC7748)].

[[Contents](#topofpage)] [[Index](#index)]

<a id="authencryptionaad"></a>Authenticated Encryption with Associated Data (AEAD)
----------------------------------------------------------------------------------

The algorithms AES with Galois/Counter Mode (AES-GCM) and ChaCha20Poly1305 provide both authenticated encryption (confidentiality and authentication) 
and the ability to check the integrity and authentication of additional authenticated data (AAD) that is sent in the clear. 
AES-GCM is specified in *NIST Special Publication 800-38D* [[SP800-38D](#SP800-38D)]
and ChaCha20Poly1305 in [[RFC8439](#RFC8439)].

There are four inputs for authenticated encryption: the secret key, initialization vector (IV) (sometimes called a nonce†), 
the plaintext itself, and optional additional authentication data (AAD). 
The nonce and AAD are passed in the clear. 
There are two outputs: the ciphertext, which is exactly the same length as the plaintext, and an authentication tag (the "tag").
The tag is sometimes called the message authentication code (MAC) or integrity check value (ICV). 

This Toolkit provides authenticated encryption using AES-GCM according to "RFC 5116 An Interface and Algorithms for Authenticated Encryption" [[RFC 5116](#RFC5116)],
and *[New in v22.0]*  using ChaCha20Poly1305 as in [[RFC8439](#RFC8439)]. We also add support for the AES-192-GCM algorithm (RFC 5116 only has AES-128-GCM and AES-256-GCM).

We add the further restriction that AES-GCM must have a fixed-length nonce (IV) of exactly 12 bytes (96 bits) and it can only create a fixed-length tag of exactly 16 bytes (128 bits). 
There is no option to use different lengths for the IV or tag.
The tag is automatically appended to the output of the encryption operation. 
The IV may optionally be prepended to the output in accordance with section 5.2.4 of "XML Encryption Syntax and Processing Version 1.1" [[XMLENC](#XMLENC)].

†
Note that the term "IV" is used here to mean exactly the same as "nonce".

[[Contents](#topofpage)] [[Index](#index)]

<a id="hybridpke"></a>Hybrid Public Key Encryption (HPKE)
---------------------------------------------------------

*[New in v22.0]*
This toolkit has all the basic cryptographic primitives required to carry out the hybrid public key encryption (HPKE) scheme
described in [[RFC9180](#RFC9180)]; namely
Elliptic Curve Diffie-Hellman (ECDH) key agreement (see [ECC_DHSharedSecret](#ECC_DHSharedSecret)), 
HMAC-based key derivation function (HKDF) using SHA2 (see [KDF_Bytes](#KDF_Bytes)),
and authenticated encryption with additional data (AEAD)
(see [CIPHER_EncryptAEAD](#CIPHER_EncryptAEAD)).

Specific functions 
[HPKE_LabeledExtract](#HPKE_LabeledExtract) and [HPKE_LabeledExpand](#HPKE_LabeledExpand)
are provided here to carry out `LabeledExtract()` and `LabeledExpand()`.
The function [HPKE_DerivePrivateKey](#HPKE_DerivePrivateKey) is provided to derive an EC private key using the deterministic method
described in HKPE. The corresponding public key can be derived using [ECC_PublicKeyFromPrivate](#ECC_PublicKeyFromPrivate).

Note that these functions are intended to be used in an object-oriented language like C# or Python, not in raw ANSI C or VB6. 
See the code `hpke_test.py` on our web site for an example.

In this implementation, the KDF algorithm is chosen automatically to match the KEM ECDH group curve as follows 
(from Table 2 in [[RFC9180](#RFC9180)]).

| KEM | ECDH group | KDF |
| --- | --- | --- |
| ``` DHKEM(P-256, HKDF-SHA256 ``` | P-256 | HKDF-SHA256 |
| ``` DHKEM(P-384, HKDF-SHA384 ``` | P-384 | HKDF-SHA384 |
| ``` DHKEM(P-521, HKDF-SHA512 ``` | P-521 | HKDF-SHA512 |
| ``` DHKEM(X25519, HKDF-SHA256 ``` | X25519 | HKDF-SHA256 |
| ``` DHKEM(X448, HKDF-SHA512 ``` | X448 | HKDF-SHA512 |

Furthermore, the ciphersuite's KDF is assumed to be always equal to the DHKEM's associated KDF from the above table.

Because these are all standalone functions with no context, the ECDH curve group used in the scheme must be specified. 
This automatically defines the KDF and associated HMAC algorithm to be used as per the above table.

The `LabeledExtract()` and `LabeledExpand()` functions facilitate domain separation of KDF calls by incorporating a `label`
and a `suite_id` which has a value derived from identifiers for the EC curve group, the KDF algorithm and, sometimes, the AEAD algorithm.
Note that the `suite_id` value is different depending on where the KDF is used. 
In this implementation, specifying the curve name will automatically select the corresponding KDF algorithm, and the absence or presence of an option flag for 
an AEAD algorithm dictates whether the KDF is being used inside a KEM algorithm (zero flag) or in the remainder of HPKE (specific AEAD algorithm flag).

The string literal "HPKE-v1" is currently hardcoded into the `LabeledExtract()` and `LabeledExpand()` functions.
Future implementations may offer an alternative if the specification is changed.

[[Contents](#topofpage)] [[Index](#index)]

<a id="prfxof"></a>HASH vs XOF vs MAC vs PRF vs KDF
---------------------------------------------------

A brief but not exhaustive description of these terms.

A (cryptographic) *hash* function takes an arbitrary length input (message) and outputs a fixed length *message digest* or *digest value*.
An *eXtendable Output Function* (XOF) is similar to a hash function but the output can be extended to any desired length. 
The security requirements of a XOF are the same as a cryptographic hash function in that it should be resistant to preimage and collision attacks. There are no secret inputs.

An example of a hash function is **SHA-256** [[FIPS180](#FIPS180)], available with [HASH_Bytes](#HASH_Bytes).
**SHAKE128** and **SHAKE256** are XOFs with security strengths of 128 bits and 256 bits respectively based on the SHA3 hash algorithm [[FIPS202](#FIPS202)], 
available with [XOF_Bytes](#XOF_Bytes).

The Mask Generation Function **MGF1** described in [[PKCS1](#PKCS1)] and used in the RSA-OEAP and RSA-PSS schemes can also be used as an XOF. 
For example, MGF1-SHA-256 is used as a XOF in the SPHINCS+ hash-based quantum-resistant signature scheme [[SPHINCS](#SPHINCS)] (see section 7.2.2, Hmsg);
it is available with [XOF_Bytes](#XOF_Bytes).

A *Message Authentication Code* (MAC) is a cryptographic checksum on data that uses a symmetric key to detect both accidental and intentional modifications of the data.

**HMAC** (*Hash-based Message Authentication Code*) is based on a hash function and takes a message and a key and outputs a security code, also called a tag. 
The security requirement for a MAC is that it must resist attempts by an adversary to forge tags. An example of an HMAC function is HMAC-SHA-256, available with [HMAC_Bytes](#HMAC_Bytes).
The output from an HMAC function is a fixed length corresponding to its underlying hash function. The output can be truncated at the cost of lower security.

**KMAC** (*KECCAK Message Authentication Code*) is a variable-length keyed hash function described in NIST SP800-185 [[SP800-185](#SP800-185)]. 
It is based on KECCAK, the core SHA-3 algorithm. 

There are two variants, KMAC128 and KMAC256, which have expected security strengths of 128 and 256 bits, respectively.
If not specified, the convention is that the output lengths for KMAC128 and KMAC256 are 256 bits (32 bytes) and 512 bits (64 bytes), respectively. 

The KMAC algorithm can theoretically output an infinitely-long stream of bytes, so it can also be used as a Pseudorandom function (PRF).
Note that you *cannot* truncate a KMAC output value when used as a message authentication code.
KMAC is available with [PRF_Bytes](#PRF_Bytes)

A *PseudoRandom Function* (PRF) takes in a secret key and a message, and outputs a bit string. 
The security requirement for a PRF is that it should behave like a random function when evaluated on arbitrary messages provided the secret key is uniformly distributed.
This is a stronger requirement than for a MAC. You can use a PRF to construct a MAC (like KMAC) but the converse is not necessarily true. A secure MAC function is not necessarily a secure PRF.

A *Key Derivation Function* (KDF) takes in some secret keying material and outputs a uniformly distributed bit string. 
The keying material does not have to be uniformly distributed and an adversary may have prior knowledge about part of it.
Thus a KDF has a stronger security requirement than a PRF. A PRF requires a uniformly-distributed secret key, but a KDF can cope with weaker material.
By definition, a KDF is a PRF, but the converse is not true.

An example of a KDF is HKDF, the HMAC-based Key Derivation Function from [[RFC5869](#RFC5869)], available with [KDF_Bytes](#KDF_Bytes).

Thus we have a hierarchy **KDF > PRF > MAC**.

[[Contents](#topofpage)] [[Index](#index)]

<a id="vb6funcsummary"></a>VB6/C Function Summary
-------------------------------------------------

These are the "raw" functions called directly by VB6/C programs. For the .NET method equivalents, see
the [List of .NET Methods](#methodlist) and
[Cross-reference between Functions and .NET Methods](#xrefdotnet).

Index:  
[ASN.1](#asn1functions) |
[Block Cipher](#cipherfunctions) |
[CMS](#cmsfunctions) |
[Conversion](#cnvfunctions) |
[Compression](#comprfunctions) |
[CRL](#crlfunctions) |
[ECC](#eccfunctions) |
[General](#genfunctions) |
[Hash](#hashfunctions) |
[HMAC](#hmacfunctions) |
[HPKE](#hpkefunctions) |
[KDF](#kdffunctions) |
[OCSP](#ocspfunctions) |
[Padding](#padfunctions) |
[PBE](#pbefunctions) |
[PEM files](#pemfunctions) |
[PFX](#pfxfunctions) |
[PRF](#prffunctions) |
[Prompt](#promptfunctions)  |
[RNG](#rngfunctions) |
[RSA Keys](#rsafunctions) |
[RSA (Raw)](#rawrsafunctions) |
[SIG](#sigfunctions) |
[S/MIME](#smimefunctions) |
[Triple DES (TDEA)](#tdeafunctions) |
[Wipe](#wipefunctions) |
[X.509 Certificates](#x509functions) |
[XOF](#xoffunctions)

### <a id="asn1functions"></a>ASN.1 analysis functions

* [`ASN1_TextDump`](#ASN1_TextDump) - Dumps details of ASN.1 formatted data to a text file.
* [`ASN1_TextDumpToString`](#ASN1_TextDumpToString) - Dumps details of ASN.1 formatted data to a string.
* [`ASN1_Type`](#ASN1_Type) - Describes the type of ASN.1 data.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="cipherfunctions"></a>Block Cipher Functions

* [`CIPHER_EncryptBytes`](#CIPHER_EncryptBytes) - Encrypts an array of bytes using specified block cipher algorithm, mode and padding.
* [`CIPHER_DecryptBytes`](#CIPHER_DecryptBytes) - Decrypts an array of bytes using specified block cipher algorithm, mode and padding.
*Supersedes:*

    + [`CIPHER_Bytes`](#CIPHER_Bytes) - Encrypts/decrypts an array of bytes using specified block cipher algorithm and mode - @deprecated.
* [`CIPHER_FileEncrypt`](#CIPHER_FileEncrypt) - Encrypts a file using specified block cipher algorithm, mode and padding.
* [`CIPHER_FileDecrypt`](#CIPHER_FileDecrypt) - Decrypts a file using specified block cipher algorithm, mode and padding.
*Supersedes:*

    + [`CIPHER_File`](#CIPHER_File) - Encrypts/decrypts a file using specified block cipher algorithm and mode - @deprecated.
* [`CIPHER_EncryptHex`](#CIPHER_EncryptHex) - Encrypt hex-encoded data using specified block cipher algorithm, mode and padding.
* [`CIPHER_DecryptHex`](#CIPHER_DecryptHex) - Decrypt hex-encoded data using specified block cipher algorithm, mode and padding. 
*Supersedes:*

    + [`CIPHER_Hex`](#CIPHER_Hex) - Encrypts/decrypts data in a hex-encoded string using specified block cipher algorithm and mode - @deprecated.
* [`CIPHER_EncryptAEAD`](#CIPHER_EncryptAEAD) - Encrypt data using an authenticated encryption algorithm.
* [`CIPHER_DecryptAEAD`](#CIPHER_DecryptAEAD) - Decrypt data using an authenticated encryption algorithm.
* [`CIPHER_KeyWrap`](#CIPHER_KeyWrap) - Wraps a content-encryption key with a key-encryption key.
* [`CIPHER_KeyUnwrap`](#CIPHER_KeyUnwrap) - Unwraps a content-encryption key with a key-encryption key.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="cmsfunctions"></a>CMS functions

* [`CMS_MakeEnvData`](#CMS_MakeEnvData) - Create a CMS enveloped-data object.
* [`CMS_MakeEnvDataFromString`](#CMS_MakeEnvDataFromString) - ditto using data directly from a string instead of a file.
* [`CMS_MakeEnvDataFromBytes`](#CMS_MakeEnvDataFromBytes) - ditto using data directly from a byte array.
* [`CMS_ReadEnvData`](#CMS_ReadEnvData) - Reads and decrypts a CMS enveloped-data object.
* [`CMS_ReadEnvDataToString`](#CMS_ReadEnvDataToString) - ditto writing data directly into a string instead of a file.
* [`CMS_ReadEnvDataToBytes`](#CMS_ReadEnvDataToBytes) - ditto writing data directly into a byte array.
* [`CMS_MakeSigData`](#CMS_MakeSigData) - Create a CMS signed-data object using sender's private key.
* [`CMS_MakeSigDataFromString`](#CMS_MakeSigDataFromString) - ditto using data directly from a string instead of a file.
* [`CMS_MakeSigDataFromBytes`](#CMS_MakeSigDataFromBytes) - ditto using data directly from a byte array.
* [`CMS_MakeSigDataFromSigValue`](#CMS_MakeSigDataFromSigValue) - ditto using a pre-computed signature value.
* [`CMS_MakeDetachedSig`](#CMS_MakeDetachedSig) - Create a "detached signature" CMS signed-data object from message digest of content.
* [`CMS_ReadSigData`](#CMS_ReadSigData) - Reads content from a CMS signed-data object file.
* [`CMS_ReadSigDataToString`](#CMS_ReadSigDataToString) - ditto writing content data into a string instead of a file.
* [`CMS_ReadSigDataToBytes`](#CMS_ReadSigDataToBytes) - ditto writing content data into a byte array.
* [`CMS_GetSigDataDigest`](#CMS_GetSigDataDigest) - Extracts message digest from a CMS signed-data object file and verifies the signature.
* [`CMS_VerifySigData`](#CMS_VerifySigData) - Verifies signature and content of a CMS signed-data object file.
* [`CMS_QuerySigData`](#CMS_QuerySigData) - Queries a CMS signed-data object file for selected information.
* [`CMS_QueryEnvData`](#CMS_QueryEnvData) - Queries a CMS enveloped-data object file for selected information.
* [`CMS_MakeComprData`](#CMS_MakeComprData) - Create a CMS compressed-data file (.p7z) from an existing input file.
* [`CMS_ReadComprData`](#CMS_ReadComprData) - Read and extract the decompressed contents of a CMS compressed-data file.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="cnvfunctions"></a>Conversion functions

* [`CNV_B64StrFromBytes`](#CNV_B64StrFromBytes) - Encodes byte data into a base64-encoded string.
* [`CNV_BytesFromB64Str`](#CNV_BytesFromB64Str) - Decodes a base64-encoded string into bytes.
* [`CNV_B64Filter`](#CNV_B64Filter) - Removes non-base64 characters from a string.
* [`CNV_HexStrFromBytes`](#CNV_HexStrFromBytes) - Encodes byte data into hexadecimal string.
* [`CNV_BytesFromHexStr`](#CNV_BytesFromHexStr) - Decodes a hexadecimal-encoded string into bytes.
* [`CNV_HexFilter`](#CNV_HexFilter) - Removes non-hexadecimal characters from a string.
* [`CNV_Base58FromBytes`](#CNV_Base58FromBytes) - Encodes an array of bytes into a base58-encoded string.
* [`CNV_Base58ToBytes`](#CNV_Base58ToBytes) - Decodes a base58-encoded string into an array of bytes.
* [`CNV_ReverseBytes`](#CNV_ReverseBytes) - Reverses the order of a byte array.
* [`CNV_NumFromBytes`](#CNV_NumFromBytes) - Converts the leftmost four bytes of an array to a 32-bit integer.
* [`CNV_NumToBytes`](#CNV_NumToBytes) - Converts a 32-bit integer to an array of 4 bytes.
* [`CNV_Latin1FromUTF8Bytes`](#CNV_Latin1FromUTF8Bytes) - Converts UTF-8 encoded array of bytes into a Latin-1 string, if possible.
* [`CNV_UTF8BytesFromLatin1`](#CNV_UTF8BytesFromLatin1) - Converts a Latin-1 string into UTF-8 encoded array of bytes.
* [`CNV_ByteEncoding`](#CNV_ByteEncoding) - Converts encoding of byte array between UTF-8 and Latin-1.
* [`CNV_CheckUTF8Bytes`](#CNV_CheckUTF8Bytes) - Checks if a byte array contains valid UTF-8.
* [`CNV_CheckUTF8File`](#CNV_CheckUTF8File) - Checks if a file contains valid UTF-8.
* [`CNV_Utf8FromWide`](#CNV_Utf8FromWide) - Maps a UTF-16 (wide character) string to a UTF-8-encoded string.
* [`CNV_ShortPathName`](#CNV_ShortPathName) - Retrieve the Windows short path form of the specified path.

The following functions are deprecated. Use the "Byte" versions instead:

* [`CNV_CheckUTF8`](#CNV_CheckUTF8) - Checks if a string is valid UTF-8 - @deprecated.
* [`CNV_Latin1FromUTF8`](#CNV_Latin1FromUTF8) - Converts a UTF-8 string into a Latin-1 string, if possible - @deprecated.
* [`CNV_UTF8FromLatin1`](#CNV_UTF8FromLatin1) - Converts a Latin-1 string into a UTF-8 string - @deprecated.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="comprfunctions"></a>Compression functions

* [`COMPR_Compress`](#COMPR_Compress) - Compress data using zlib compression.
* [`COMPR_Uncompress`](#COMPR_Uncompress) - Uncompress data using zlib compression.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="crlfunctions"></a>Certificate Revocation List (CRL) functions

* [`X509_MakeCRL`](#X509_MakeCRL) - Creates an X.509 Certificate Revocation List (CRL).
* [`X509_CheckCertInCRL`](#X509_CheckCertInCRL) - checks whether an X.509 certificate has been revoked in a Certificate Revocation List (CRL).

[[Contents](#topofpage)] [[Index](#index)]

### <a id="eccfunctions"></a>Elliptic curve cryptography functions

* [`ECC_MakeKeys`](#ECC_MakeKeys) - Generate an EC public/private key pair and save as two key files.
* [`ECC_ReadKeyByCurve`](#ECC_ReadKeyByCurve) - Read an EC key from its hexadecimal (base16) representation.
* [`ECC_ReadPrivateKey`](#ECC_ReadPrivateKey) - Read an EC private key from a file into an internal key string.
* [`ECC_ReadPublicKey`](#ECC_ReadPublicKey) - Read an EC public key from a file into an internal key string.
* [`ECC_SaveEncKey`](#ECC_SaveEncKey) - Save an internal EC private key string to an encrypted private key file.
* [`ECC_SaveKey`](#ECC_SaveKey) - Save an internal EC key string to a key file.
* [`ECC_PublicKeyFromPrivate`](#ECC_PublicKeyFromPrivate) - Convert an internal EC private key string into an internal public key string.
* [`ECC_QueryKey`](#ECC_QueryKey) - Query an EC key string for selected information.
* [`ECC_KeyHashCode`](#ECC_KeyHashCode) - Compute the hash code of an "internal" ECC public or private key string.
* [`ECC_DHSharedSecret`](#ECC_DHSharedSecret) - Compute EC Diffie-Hellman (ECDH) shared secret.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="genfunctions"></a>General functions

* [`PKI_LastError`](#PKI_LastError) - Get the last error message set by the toolkit.
* [`PKI_ErrorCode`](#PKI_ErrorCode) - Return the last error code.
* [`PKI_ErrorLookup`](#PKI_ErrorLookup) - Get a description of an error code.
* [`PKI_Version`](#PKI_Version) - Get the release version as an integer value.
* [`PKI_CompileTime`](#PKI_CompileTime) - Get date and time the DLL was last compiled.
* [`PKI_ModuleName`](#PKI_ModuleName) - Get the name of process module.
* [`PKI_ModuleInfo`](#PKI_ModuleInfo) - Get additional information about the core DLL module.
* [`PKI_PowerUpTests`](#PKI_PowerUpTests) - Carry out power-up tests.
* [`PKI_LicenceType`](#PKI_LicenceType) - Return the licence type.
* [`PKI_Platform`](#PKI_Platform) - Gets the platform of the core DLL.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="hashfunctions"></a>Message Digest Hash Functions

* [`HASH_Bytes`](#HASH_Bytes) - Creates a cryptographic hash digest in byte format from byte data.
* [`HASH_File`](#HASH_File) - Creates a cryptographic hash digest in byte format from a file.
* [`HASH_HexFromBytes`](#HASH_HexFromBytes) - Creates a cryptographic hash digest in hex format from byte data.
* [`HASH_HexFromFile`](#HASH_HexFromFile) - Creates a cryptographic hash digest in hex format from a file.
* [`HASH_HexFromHex`](#HASH_HexFromHex) - Creates a cryptographic hash digest in hex format from hex-encoded data.
* [`HASH_Length`](#HASH_Length) - Return length of the message digest in bytes.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="hmacfunctions"></a>HMAC Functions

* [`HMAC_Bytes`](#HMAC_Bytes) - Creates a keyed-hash HMAC in byte format from byte data.
* [`HMAC_HexFromBytes`](#HMAC_HexFromBytes) - Creates a keyed-hash HMAC in hex format from byte data.
* [`HMAC_HexFromHex`](#HMAC_HexFromHex) - Creates a keyed-hash HMAC in hex format from hex-encoded data.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="hpkefunctions"></a>Hybrid Public Key Encryption (HPKE) functions

* [`HPKE_DerivePrivateKey`](#HPKE_DerivePrivateKey) - Derive an EC private key in a deterministic manner from input keying material using the DeriveKeyPair algorithm in RFC9180.
* [`HPKE_LabeledExpand`](#HPKE_LabeledExpand) - Compute the output of the LabeledExpand function as defined in RFC9180.
* [`HPKE_LabeledExtract`](#HPKE_LabeledExtract) - Compute the output of the LabeledExtract function as defined in RFC9180.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="kdffunctions"></a>Key Derivation Functions

* [`KDF_Bytes`](#KDF_Bytes) - Generate a key-encryption key (KEK) from input keying material using a key derivation function (KDF).
* [`KDF_ForCms`](#KDF_ForCms) - Generate a key-encryption key (KEK) for ECDH key exchange in a CMS EnvelopedData object.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="ocspfunctions"></a>OCSP Functions

* [`OCSP_MakeRequest`](#OCSP_MakeRequest) - Creates an Online Certification Status Protocol (OCSP) request as a base64 string.
* [`OCSP_ReadResponse`](#OCSP_ReadResponse) - Reads a response to an Online Certification Status Protocol (OCSP) request and outputs the main results in text form.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="padfunctions"></a>Padding functions

* [`PAD_BytesBlock`](#PAD_BytesBlock) - Creates an input block suitably padded for encryption by a block cipher in ECB or CBC mode.
* [`PAD_UnpadBytes`](#PAD_UnpadBytes) - Removes the padding from an encryption block.
* [`PAD_HexBlock`](#PAD_HexBlock) - Creates a hex-encoded input block suitably padded for encryption by a block cipher in ECB or CBC mode.
* [`PAD_UnpadHex`](#PAD_UnpadHex) - Removes the padding from a hex-encoded encryption block.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="pbefunctions"></a>Password-based encryption functions

* [`PBE_Kdf2`](#PBE_Kdf2) - Derives a key of any length from a password using the PBKDF2 algorithm from PKCS #5.
* [`PBE_Kdf2Hex`](#PBE_Kdf2Hex) - Derives a key of any length from a password using the PBKDF2 algorithm from PKCS #5 with the salt and output derived key encoded in hexadecimal.
* [`PBE_Scrypt`](#PBE_Scrypt) - Derives a key of any length from a password using the SCRYPT algorithm.
* [`PBE_ScryptHex`](#PBE_ScryptHex) - Derives a key of any length from a password using the SCRYPT algorithm with the salt and derived key encoded in hexadecimal.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="pemfunctions"></a>PEM/binary file conversion functions

* [`PEM_FileFromBinFile`](#PEM_FileFromBinFile) - Converts a binary file into a PEM file.
* [`PEM_FileFromBinFileEx`](#PEM_FileFromBinFileEx) - Converts a binary file into a PEM file with extended options.
* [`PEM_FileToBinFile`](#PEM_FileToBinFile) - Converts the contents of a PEM file into a binary file.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="pfxfunctions"></a>PFX Functions

* [`PFX_MakeFile`](#PFX_MakeFile) - Creates a simple PFX (PKCS-12) file from X.509 certificate and (optional) encrypted private key file.
* [`PFX_VerifySig`](#PFX_VerifySig) - Verifies a PFX (PKCS-12) file signature.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="prffunctions"></a>Pseudorandom functions (PRF)

* [`PRF_Bytes`](#PRF_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

### <a id="promptfunctions"></a>Password prompt functions

* [`PWD_Prompt`](#PWD_Prompt) - Prompts for a password.
* [`PWD_PromptEx`](#PWD_PromptEx) - Prompts for a password with extra options.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="rngfunctions"></a>Random number generator functions

* [`RNG_Bytes`](#RNG_Bytes) - Generates a random set of byte data.
* [`RNG_BytesWithPrompt`](#RNG_BytesWithPrompt) - ditto with a prompt to enter random keystrokes.
* [`RNG_String`](#RNG_String) - Generates a string of random chars (classic VB6/VBA only) - @deprecated.
* [`RNG_StringWithPrompt`](#RNG_StringWithPrompt) - Generates a string of random chars with a prompt (classic VB6/VBA only) - @deprecated.
* [`RNG_Number`](#RNG_Number) - Generates a random number in a given range.
* [`RNG_Guid`](#RNG_Guid) - Generate a random 36-character Global Unique IDentifier (GUID) string.
* [`RNG_Initialize`](#RNG_Initialize) - Initializes the RNG from a seed file.
* [`RNG_MakeSeedFile`](#RNG_MakeSeedFile) - Creates a new seed file, prompting for entropy.
* [`RNG_UpdateSeedFile`](#RNG_UpdateSeedFile) - Updates an existing seed file.
* [`RNG_Test`](#RNG_Test) - Carries out a health check and a FIPS-140-2 statistical test on the RNG.
* [`RNG_TestDRBGVS`](#RNG_TestDRBGVS) - Test the RNG for conformance to NIST SP800-90A using the relevant test specified in DRBGVS.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="rsafunctions"></a>RSA key functions

* [`RSA_MakeKeysXtd`](#RSA_MakeKeysXtd) - Generate an RSA key pair and save as two key files.
	*Supersedes:*

    + [`RSA_MakeKeys`](#RSA_MakeKeys) - Generate an RSA key pair - @deprecated.
* [`RSA_ReadAnyPrivateKey`](#RSA_ReadAnyPrivateKey) - Reads from a file or string containing a private key into an "internal" private key string.
	*Supersedes:*

    + [`RSA_ReadEncPrivateKey`](#RSA_ReadEncPrivateKey) - Reads private key string from a PKCS-8 EncryptedPrivateKeyInfo file - @deprecated.
        + [`RSA_ReadPrivateKeyInfo`](#RSA_ReadPrivateKeyInfo) - Reads private key string from an (unencrypted) PrivateKeyInfo file - @deprecated.
        + [`RSA_ReadPrivateKeyFromPFX`](#RSA_ReadPrivateKeyFromPFX) - Reads private key string from a PKCS-12 PKCSShroudedKeybag - @deprecated.
* [`RSA_ReadAnyPublicKey`](#RSA_ReadAnyPublicKey) - Reads from a file or string containing a public key into an "internal" public key string.
	*Supersedes:*

    + [`RSA_ReadPublicKey`](#RSA_ReadPublicKey) - Reads public key string from a PKCS-1 RSAPublicKey file - @deprecated.
        + [`RSA_GetPublicKeyFromCert`](#RSA_GetPublicKeyFromCert) - Reads public key string from an X.509 certificate - @deprecated.
* [`RSA_SaveEncKey`](#RSA_SaveEncKey) - Save an internal RSA private key string to an encrypted private key file.
	*Supersedes:*

    + [`RSA_SaveEncPrivateKey`](#RSA_SaveEncPrivateKey) - Saves a private key string to a PKCS-8 EncryptedPrivateKeyInfo file - @deprecated.
* [`RSA_SavePrivateKeyInfo`](#RSA_SavePrivateKeyInfo) - Saves a private key string to an (unencrypted) PKCS-8 PrivateKeyInfo file.
* [`RSA_SavePublicKey`](#RSA_SavePublicKey) - Saves a public key in a PKCS-1 RSAPublicKey file.
* [`RSA_PublicKeyFromPrivate`](#RSA_PublicKeyFromPrivate) - Converts an internal RSA private key string into an internal public key string.
* [`RSA_GetPrivateKeyFromPFX`](#RSA_GetPrivateKeyFromPFX) - Extracts a private key file from a PKCS-12 PKCSShroudedKeybag.
* [`RSA_ToXMLString`](#RSA_ToXMLString) - Creates an XML string representation of an RSA internal key string.
* [`RSA_ToXMLStringEx`](#RSA_ToXMLStringEx) - Creates an XML string representation of an RSA internal key string with option to add a namespace prefix.
* [`RSA_FromXMLString`](#RSA_FromXMLString) - Creates an RSA key string in internal format from an XML string.
* [`RSA_CheckKey`](#RSA_CheckKey) - Checks if an RSA key string is valid.
* [`RSA_KeyBits`](#RSA_KeyBits) - Returns length of key in bits given public or private key string.
* [`RSA_KeyBytes`](#RSA_KeyBytes) - Returns length of key in bytes given public or private key string.
* [`RSA_KeyHashCode`](#RSA_KeyHashCode) - Returns a hash code of a public or private key string.
* [`RSA_KeyMatch`](#RSA_KeyMatch) - Verifies that a pair of private and public key strings are matched.
* [`RSA_KeyValue`](#RSA_KeyValue) - Extracts a base64-encoded RSA key value from internal key string.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="rawrsafunctions"></a>Raw RSA functions

* [`RSA_RawPublic`](#RSA_RawPublic) - Transforms raw data using an RSA public key.
* [`RSA_RawPrivate`](#RSA_RawPrivate) - Transforms raw data using an RSA private key.
* [`RSA_EncodeMsg`](#RSA_EncodeMsg) - Creates an EME or EMSA encoded message block according to PKCS#1.
* [`RSA_DecodeMsg`](#RSA_DecodeMsg) - Decodes an EME or EMSA encoded message block according to PKCS#1.
* [`RSA_Encrypt`](#RSA_Encrypt) - Encrypt a short message using RSA encryption.
* [`RSA_Decrypt`](#RSA_Decrypt) - Decrypt a message encrypted using RSA encryption.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="sigfunctions"></a>SIG functions

* [`SIG_SignData`](#SIG_SignData) - Compute a signature value over data in a byte array.
* [`SIG_SignFile`](#SIG_SignFile) - Compute a signature value over data in a file.
* [`SIG_VerifyData`](#SIG_VerifyData) - Verify a signature value over data in a byte array.
* [`SIG_VerifyFile`](#SIG_VerifyFile) - Verify a signature value over data in a file.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="smimefunctions"></a>S/MIME functions

* [`SMIME_Wrap`](#SMIME_Wrap) - Wrap a CMS object in an S/MIME entity.
* [`SMIME_Extract`](#SMIME_Extract) - Extract the body from an S/MIME entity.
* [`SMIME_Query`](#SMIME_Query) - Query an S/MIME entity.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="tdeafunctions"></a>Triple DES (TDEA/3DES) Functions

* [`TDEA_BytesMode`](#TDEA_BytesMode) - Encrypts/decrypts an array of bytes using Triple DES.
* [`TDEA_HexMode`](#TDEA_HexMode) - Encrypts/decrypts a hex-encoded string using Triple DES with hex-encoded key and IV.
* [`TDEA_B64Mode`](#TDEA_B64Mode) - Encrypts/decrypts a base64-encoded string using Triple DES with base64-encoded key and IV.
* [`TDEA_File`](#TDEA_File) - Encrypts/decrypts a file using Triple DES and PKCS#5/#7 padding.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="wipefunctions"></a>Wipe functions

* [`WIPE_File`](#WIPE_File) - Securely wipes a file using 7-pass DOD standards.
* [`WIPE_Data`](#WIPE_Data) - Zeroises data in memory.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="x509functions"></a>X.509 certificate functions

* [`X509_MakeCert`](#X509_MakeCert) - Creates an X.509 certificate.
* [`X509_MakeCertSelf`](#X509_MakeCertSelf) - Creates a self-signed X.509 certificate.
* [`X509_CertRequest`](#X509_CertRequest) - Creates a PKCS-10 certification signing request (CSR).
* [`X509_VerifyCert`](#X509_VerifyCert) - Verifies that an X.509 certificate has been signed by its issuer.
* [`X509_CertThumb`](#X509_CertThumb) - Calculates the message digest thumbprint of an X.509 certificate.
* [`X509_CertIsValidNow`](#X509_CertIsValidNow) - Verifies that an X.509 certificate is currently valid.
* [`X509_CertIssuedOn`](#X509_CertIssuedOn) - Returns string containing date and time certificate was issued on.
* [`X509_CertExpiresOn`](#X509_CertExpiresOn) - Returns string containing date and time certificate expires.
* [`X509_CertSerialNumber`](#X509_CertSerialNumber) - Extracts serial number of X.509 certificate.
* [`X509_CertIssuerName`](#X509_CertIssuerName) - Extracts issuer's distinguished name from X.509 certificate.
* [`X509_CertSubjectName`](#X509_CertSubjectName) - Extracts subject's distinguished name from X.509 certificate.
* [`X509_HashIssuerAndSN`](#X509_HashIssuerAndSN) - Calculates the message digest hash of the issuer-and-serial-number value of an X.509 certificate.
* [`X509_GetCertFromP7Chain`](#X509_GetCertFromP7Chain) - Extracts an X.509 certificate file from a PKCS-7 "certs-only" certificate chain file.
* [`X509_GetCertFromPFX`](#X509_GetCertFromPFX) - Extracts an X.509 certificate file from a PKCS-12 PFX/.p12 file.
* [`X509_ReadCertStringFromP7Chain`](#X509_ReadCertStringFromP7Chain) - Reads an X.509 certificate into a base64 string from PKCS-7 "certs-only" data.
* [`X509_ReadCertStringFromPFX`](#X509_ReadCertStringFromPFX) - Reads an X.509 certificate into a base64 string from PKCS-12 PFX/.p12 data.
* [`X509_KeyUsageFlags`](#X509_KeyUsageFlags) - Returns a bitfield containing the keyUsage flags.
* [`X509_QueryCert`](#X509_QueryCert) - Queries a X.509 certificate file for selected information.
* [`X509_ReadStringFromFile`](#X509_ReadStringFromFile) - Creates a base64 string of the X.509 certificate file.
* [`X509_SaveFileFromString`](#X509_SaveFileFromString) - Creates a new X.509 certificate file from a base64 string.
* [`X509_TextDump`](#X509_TextDump) - Dumps details of X.509 certificate (or CRL or CSR) to a text file.
* [`X509_TextDumpToString`](#X509_TextDumpToString) - Dumps details of X.509 certificate (or CRL or CSR) to a string.
* [`X509_ValidatePath`](#X509_ValidatePath) - Validates a certificate path.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="xoffunctions"></a>eXtendable-output functions (XOF)

* [`XOF_Bytes`](#XOF_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="functionlist"></a>List of Functions
------------------------------------------

Index:  
[ASN.1](#asn1functions) |
[Block Cipher](#cipherfunctions) |
[CMS](#cmsfunctions) |
[Conversion](#cnvfunctions) |
[Compression](#comprfunctions) |
[CRL](#crlfunctions) |
[ECC](#eccfunctions) |
[General](#genfunctions) |
[Hash](#hashfunctions) |
[HMAC](#hmacfunctions) |
[HPKE](#hpkefunctions) |
[KDF](#kdffunctions) |
[OCSP](#ocspfunctions) |
[Padding](#padfunctions) |
[PBE](#pbefunctions) |
[PEM files](#pemfunctions) |
[PFX](#pfxfunctions) |
[PRF](#prffunctions) |
[Prompt](#promptfunctions)  |
[RNG](#rngfunctions) |
[RSA Keys](#rsafunctions) |
[RSA (Raw)](#rawrsafunctions) |
[SIG](#sigfunctions) |
[S/MIME](#smimefunctions) |
[Triple DES (TDEA)](#tdeafunctions) |
[Wipe](#wipefunctions) |
[X.509 Certificates](#x509functions) |
[XOF](#xoffunctions)

<a id="ASN1_TextDump"></a>ASN1_TextDump
---------------------------------------

Dumps details of ASN.1 formatted data to a text file

### VBA/VB6 Syntax

`Public Declare Function ASN1_TextDump Lib "diCrPKI.dll" (ByVal strFileOut As String, ByVal strFileOrPEMString As String, ByVal nOptions As Long) As Long`

`nRet = ASN1_TextDump(strFileOut, strFileOrPEMString, nOptions)`

### C/C++ Syntax

`long __stdcall ASN1_TextDump(const char *szFileOut, const char *szFileOrPEMString, long nOptions);`

### Parameters

*szFileOut*
:   [in] filename of text file to be created.

*szFileOrPEMString*
:   [in] filename of ASN.1 formatted data file to be analyzed
	(or its [base64 representation](#base64forcert)
	or [PEM string](#pemstring)).

*nOptions*
:   [in] option flags:  

`PKI_ASN1_NOCOMMENTS` to hide the comments  

`PKI_ASN1_ADDLEVELS` to show level numbers

### Returns (VBA/C)

If successful, the return value is zero; otherwise it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

[Asn1.TextDump Method](#M_Asn1_TextDump)  

### C++ (STL) Equivalent

static int [dipki::Asn1::TextDump](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_asn1.html#afada981d58be3f2c270f7729f345818e "External link") (const std::string &outputFile, const std::string &asn1File, Opts opts=Opts::None)

### Python Equivalent

static [Asn1.text_dump](https://cryptosys.net/pki/pydocpki/class-stubs/Asn1.html#cryptosyspki.Asn1.text_dump "External link")(outputfile, asn1file, opts=0)

### Remarks

The input may be a binary file in BER/DER format or a text file in PEM or base64-encoded format, 
or may be passed as a [base64 string](#base64forcert) or as a [PEM string](#pemstring).

Only data with an outer SEQUENCE is accepted, which is the rule for all common PKI-related ASN.1 files.

The output is a text file showing the structure of the ASN.1 formatted data.
All the bytes in the input are printed in hexadecimal form laid out to show the nested structure of the ASN.1 formatted data
together with comments beginning with `"--"` that give further details about the elements. 
The length of each object is shown in bytes, for example

```

30 81 e0  --SEQUENCE/224 bytes

```

shows the tag (`30`) and length bytes (`81 e0`) which begin a SEQUENCE of length 224 bytes, equal to hexadecimal E0 bytes.

Use the `PKI_ASN1_NOCOMMENTS` option to hide the comments: the resulting hexadecimal output without comments should decode back
directly to the original binary file.

### Example

```

Dim nRet As Long
Dim strInputFile As String
Dim strOutFile As String

strInputFile = "smallca.cer"
strOutFile = "dumpasn1-smallca.cer.txt"
Debug.Print "File: " & strInputFile
nRet = ASN1_TextDump(strOutFile, strInputFile, 0)
Debug.Print "ASN1_TextDump returns " & nRet
ShowTextFile strOutFile
' Pass input as a string
strInputFile = "MAQwAgUA"
strOutFile = "dumpasn1.txt"
Debug.Print "Input: " & strInputFile
nRet = ASN1_TextDump(strOutFile, strInputFile, 0)
Debug.Print "ASN1_TextDump returns " & nRet
ShowTextFile strOutFile
' Again with no comments
nRet = ASN1_TextDump(strOutFile, strInputFile, PKI_ASN1_NOCOMMENTS)
Debug.Print "ASN1_TextDump returns " & nRet
ShowTextFile strOutFile

```

```

File: smallca.cer
ASN1_TextDump returns 0
30 81 e0  --SEQUENCE/224 bytes
   30 81 9a  --SEQUENCE/154 bytes
      02 01  --INTEGER/1 bytes
         01
      30 0d  --SEQUENCE/13 bytes
         06 09  --OBJECTIDENTIFIER/9 bytes
            2a 86 48 86 f7 0d 01 01 05
            --sha1WithRSAEncryption (1.2.840.113549.1.1.5)
         05 00  --NULL/0 bytes
      30 0c  --SEQUENCE/12 bytes
         31 0a  --SET/10 bytes
            30 08  --SEQUENCE/8 bytes
               06 03  --OBJECTIDENTIFIER/3 bytes
                  55 04 03
                  --commonName (2.5.4.3)
               13 01  --PRINTABLESTRING/1 bytes
                  41
                  --'A'
      30 1e  --SEQUENCE/30 bytes
         17 0d  --UTCTIME/13 bytes
            39 39 30 39 31 39 30 31 30 38 34 37 5a
            --'990919010847Z'
         17 0d  --UTCTIME/13 bytes
            33 39 31 32 33 31 32 33 35 39 35 39 5a
            --'391231235959Z'
      30 0c  --SEQUENCE/12 bytes
         31 0a  --SET/10 bytes
            30 08  --SEQUENCE/8 bytes
               06 03  --OBJECTIDENTIFIER/3 bytes
                  55 04 03
                  --commonName (2.5.4.3)
               13 01  --PRINTABLESTRING/1 bytes
                  41
                  --'A'
      30 4a  --SEQUENCE/74 bytes
         30 0d  --SEQUENCE/13 bytes
            06 09  --OBJECTIDENTIFIER/9 bytes
               2a 86 48 86 f7 0d 01 01 01
               --rsaEncryption (1.2.840.113549.1.1.1)
            05 00  --NULL/0 bytes
         03 39  --BITSTRING/57 bytes
            00 --0 unused bits
            --encapsulates:
            30 36  --SEQUENCE/54 bytes
               02 31  --INTEGER/49 bytes
                  02 f9 09 6a 7d 83 55 c2 71 ae f1 6a cb 45 41 ba
                  b3 22 a2 83 b5 ad de 70 e3 37 19 a7 c9 bb ee 76
                  4b e2 fc b8 5c c7 9b e2 3f 27 1f 6f b7 b5 36 80
                  19
               02 01  --INTEGER/1 bytes
                  03
   30 0d  --SEQUENCE/13 bytes
      06 09  --OBJECTIDENTIFIER/9 bytes
         2a 86 48 86 f7 0d 01 01 05
         --sha1WithRSAEncryption (1.2.840.113549.1.1.5)
      05 00  --NULL/0 bytes
   03 32  --BITSTRING/50 bytes
      00 --0 unused bits
      01 9a 9b b2 ec b9 cd fd 66 c6 94 5b 2e d6 96 dc
      32 87 68 da 5e 6f 2e 5d 5a 7f e6 09 2e 60 8f 8c
      45 a5 18 7e 06 1c e9 81 aa ea d6 f2 e3 14 7d 25
      91
--(227 bytes)

Input: MAQwAgUA
ASN1_TextDump returns 0
30 04  --SEQUENCE/4 bytes
   30 02  --SEQUENCE/2 bytes
      05 00  --NULL/0 bytes
--(6 bytes)

ASN1_TextDump returns 0
30 04 
   30 02 
      05 00 

```

### See Also

[ASN1_TextDumpToString](#ASN1_TextDumpToString)
[ASN1_Type](#ASN1_Type)

[[Contents](#topofpage)] [[Index](#index)]

<a id="ASN1_TextDumpToString"></a>ASN1_TextDumpToString
-------------------------------------------------------

Dumps details of ASN.1 formatted data to a string.

### VBA/VB6 Syntax

`Public Declare Function ASN1_TextDumpToString Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strFileOrPEMString As String, ByVal strDirName As String, ByVal nOptions As Long) As Long`

`nRet = ASN1_TextDumpToString(strOutput, nOutChars, strFileOrPEMString, nOptions)`

### C/C++ Syntax

`long __stdcall ASN1_TextDumpToString(char *szOutput, long nOutChars, const char *szFileOrPEMString, const char *szDirName, long nOptions);`

### Parameters

*szOutput*
:   [out] String buffer to receive output.

*nOutChars*
:   [in] Maximum number of characters to be received.

*szFileOrPEMString*
:   [in] Filename of ASN.1 formatted data file to be analyzed
	(or its [base64 representation](#base64forcert)
	or [PEM string](#pemstring)).

*szDirName*
:   [in] Directory in which to create a temporary file. Specify `""` for default = system `TEMP` directory.

*nOptions*
:   [in] option flags:  

`PKI_ASN1_NOCOMMENTS` to hide the comments  

`PKI_ASN1_ADDLEVELS` to show level numbers

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string; otherwise it returns a nonzero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`asn1TextDumpToString`](#VB_asn1TextDumpToString) (szFileOrPEMString As String, Optional nOptions As Long = 0, Optional szDirName As String = "") As String

### .NET Equivalent

[Asn1.TextDumpToString Method](#M_Asn1_TextDumpToString)  

### C++ (STL) Equivalent

static std::string [dipki::Asn1::TextDumpToString](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_asn1.html#a8a9c6f7105357424caaecac677ec056b "External link") (const std::string &asn1File, Opts opts=Opts::None)

### Python Equivalent

static [Asn1.text_dump_tostring](https://cryptosys.net/pki/pydocpki/class-stubs/Asn1.html#cryptosyspki.Asn1.text_dump_tostring "External link")(asn1file, opts=0)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The input may be a binary file in BER/DER format or a text file in PEM or base64-encoded format, 
or may be passed as a [base64 string](#base64forcert) or as a [PEM string](#pemstring).

Only data with an outer SEQUENCE is accepted, which is the rule for all common PKI-related ASN.1 files.

The output is a text file showing the structure of the ASN.1 formatted data.
All the bytes in the input are printed in hexadecimal form laid out to show the nested structure of the ASN.1 formatted data
together with comments beginning with `"--"` that give further details about the elements. 
The length of each object is shown in bytes, for example

```

30 81 e0  --SEQUENCE/224 bytes

```

shows the tag (`30`) and length bytes (`81 e0`) which begin a SEQUENCE of length 224 bytes, equal to hexadecimal E0 bytes.

Use the `PKI_ASN1_NOCOMMENTS` option to hide the comments: the resulting hexadecimal output without comments should decode back
directly to the original binary file.

This function creates a temporary file, by default in the system `TEMP` directory. This file is locked and is automatically deleted after use.
The user can specify a particular directory known to be secure if required. If the specified directory does not exist, the system `TEMP` directory will be used.

### Example (VBA core function)

```

Dim strInputFile As String
Dim strBuffer As String
Dim nChars As Long

' Pass input as a string
strInputFile = "MAQwAgUA"
Debug.Print "Input: " & strInputFile
' Query for required length
nChars = ASN1_TextDumpToString("", 0, strInputFile, "", 0)
Debug.Print "ASN1_TextDumpToString returns " & nChars
' Dimension output buffer
strBuffer = String(nChars, " ")
nChars = ASN1_TextDumpToString(strBuffer, Len(strBuffer), strInputFile, "", 0)
Debug.Print strBuffer
' Again with no comments
strBuffer = String(nChars, " ")
nChars = ASN1_TextDumpToString(strBuffer, Len(strBuffer), strInputFile, "", PKI_ASN1_NOCOMMENTS)
Debug.Print "ASN1_TextDumpToString returns " & nChars
Debug.Print Left(strBuffer, nChars)

```

```

Input: MAQwAgUA
ASN1_TextDumpToString returns 95
30 04  --SEQUENCE/4 bytes
   30 02  --SEQUENCE/2 bytes
      05 00  --NULL/0 bytes
--(6 bytes)

ASN1_TextDumpToString returns 30
30 04 
   30 02 
      05 00 	

```

### Example (VBA wrapper function)

```

Debug.Print x509TextDumpToString("AliceRSASignByCarl.cer")
Debug.Print x509QueryCert("AliceRSASignByCarl.cer", "subjectName")
Debug.Print asn1TextDumpToString("AliceRSASignByCarl.cer")

```

```

Dim strInput As String
Dim strOutput As String
strInput = "MAQwAgUA"
Debug.Print "Input: " & strInput
strOutput = asn1TextDumpToString(strInput)
Debug.Print strOutput
Debug.Print asn1TextDumpToString(strInput, PKI_ASN1_NOCOMMENTS)

```

### See Also

[ASN1_TextDump](#ASN1_Type)
[ASN1_Type](#ASN1_Type)

[[Contents](#topofpage)] [[Index](#index)]

<a id="ASN1_Type"></a>ASN1_Type
-------------------------------

Describes the type of ASN.1 data.

### VBA/VB6 Syntax

`Public Declare Function ASN1_Type Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strFileOrPEMString As String, ByVal nOptions As Long) As Long`

`nRet = ASN1_Type(strOutput, nOutChars, strFileOrPEMString, nOptions)`

### C/C++ Syntax

`long __stdcall ASN1_Type(char *szOutput, long nOutChars, const char *szFileOrPEMString, long nOptions);`

### Parameters

*szOutput*
:   [out] string of sufficient length to receive the output 
	(guaranteed not to be longer than `PKI_ASN1_TYPE_MAXCHARS`).

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szFileOrPEMString*
:   [in] filename of ASN.1 formatted data file to be analyzed 
	(or its [base64 representation](#base64forcert)
	or [PEM string](#pemstring)).

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string; 
otherwise it returns a negative [error code](#errorcodes). 

### VBA Wrapper Syntax

Public Function [`asn1Type`](#VB_asn1Type) (szFileOrPEMString As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Asn1.Type Method](#M_Asn1_Type)  

### C++ (STL) Equivalent

static std::string [dipki::Asn1::Type](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_asn1.html#abe66fd14daf02c34fa6221b8ff39c230 "External link") (const std::string &asn1File)

### Python Equivalent

static [Asn1.type](https://cryptosys.net/pki/pydocpki/class-stubs/Asn1.html#cryptosyspki.Asn1.type "External link")(asn1file)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The input may be a binary file in BER/DER format or a text file in PEM or base64 format, 
or may be passed as a [base64 string](#base64forcert) or as a [PEM string](#pemstring).
The output is a string describing the most likely type of the ASN.1-formatted data,
or an empty string (`""`) if the type cannot be determined.
The following types are detected:

| Output string value | ASN.1 object type | Reference |
| --- | --- | --- |
| EC PRIVATE KEY | `ECPrivateKey` | [[RFC5915](#RFC5915)] |
| OCSP REQUEST | `OCSPRequest` | [[RFC6960](#RFC6960)] |
| OCSP RESPONSE | `OCSPResponse` | [[RFC6960](#RFC6960)] |
| PKCS1 RSA PRIVATE KEY | `RSAPrivateKey` | [[RFC3447](#RFC3447)] |
| PKCS1 RSA PUBLIC KEY | `RSAPublicKey` | [[RFC3447](#RFC3447)] |
| PKCS10 CERTIFICATE REQUEST | `CertificationRequest` | [[RFC2986](#RFC2986)] |
| PKCS12 PFX | `PFX` | [[RFC7292](#RFC7292)] |
| PKCS7 CERTIFICATE CHAIN | `ContentInfo` | [[RFC5652](#RFC5652)] |
| PKCS7/CMS COMPRESSED DATA | `ContentInfo` | [[RFC3274](#RFC3274)] |
| PKCS7/CMS DATA | `ContentInfo` | [[RFC5652](#RFC5652)] |
| PKCS7/CMS ENVELOPED DATA | `ContentInfo` | [[RFC5652](#RFC5652)] |
| CMS AUTH ENVELOPED DATA | `ContentInfo` | [[RFC5083](#RFC5083)] |
| PKCS7/CMS SIGNED DATA | `ContentInfo` | [[RFC5652](#RFC5652)] |
| PKCS8 ENCRYPTED PRIVATE KEY | `EncryptedPrivateKeyInfo` | [[RFC5208](#RFC5208)], [[RFC5958](#RFC5958)] |
| PKCS8 PRIVATE KEY INFO | `PrivateKeyInfo` | [[RFC5208](#RFC5208)], [[RFC5958](#RFC5958)] |
| PKCS8 ONE ASYMMETRIC KEY | `OneAsymmetricKey` | [[RFC5958](#RFC5958)] |
| PUBLIC KEY INFO | `SubjectPublicKeyInfo` | [[RFC3279](#RFC3279)], [[RFC5480](#RFC5480)] |
| X509 CERTIFICATE | `Certificate` | [[RFC5280](#RFC5280)] |
| X509 CRL | `CertificateList` | [[RFC5280](#RFC5280)] |

Note that these descriptions are not necessarily those used as labels for PEM formatted files.
See [PEM_FileFromBinFile](#PEM_FileFromBinFile) and [[RFC7468](#RFC7468)].

### Example (VBA core function)

```

Dim nChars As Long
Dim strTypeName As String

' Output guaranteed not to be longer than PKI_ASN1_TYPE_MAXCHARS characters
strTypeName = String(PKI_ASN1_TYPE_MAXCHARS, " ")
nChars = ASN1_Type(strTypeName, Len(strTypeName), "AliceRSASignByCarl.cer", 0)
If nChars > 0 Then Debug.Print Left(strTypeName, nChars)

strTypeName = String(PKI_ASN1_TYPE_MAXCHARS, " ")
nChars = ASN1_Type(strTypeName, Len(strTypeName), "AlicePrivRSASign.pri", 0)
If nChars > 0 Then Debug.Print Left(strTypeName, nChars)

strTypeName = String(PKI_ASN1_TYPE_MAXCHARS, " ")
nChars = ASN1_Type(strTypeName, Len(strTypeName), "BobPrivRSAEncrypt.p8e", 0)
If nChars > 0 Then Debug.Print Left(strTypeName, nChars)
  
strTypeName = String(PKI_ASN1_TYPE_MAXCHARS, " ")
nChars = ASN1_Type(strTypeName, Len(strTypeName), "rfc3280bis_CRL.crl", 0)
If nChars > 0 Then Debug.Print Left(strTypeName, nChars)

```

```

X509 CERTIFICATE
PKCS8 PRIVATE KEY INFO
PKCS8 ENCRYPTED PRIVATE KEY
X509 CRL

```

### Example (VBA wrapper function)

```

Debug.Print asn1Type("AliceRSASignByCarl.cer", 0)
Debug.Print asn1Type("BobPrivRSAEncrypt.p8e", 0)
Debug.Print asn1Type("bad.file", 0)
```

### See Also

[ASN1_TextDump](#ASN1_TextDump)
[PEM_FileFromBinFile](#PEM_FileFromBinFile)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CIPHER_Bytes"></a>CIPHER_Bytes
-------------------------------------

Encrypt or decrypt data in a byte array. The key and initialization vector are given as byte arrays.
  

@deprecated 
Use [CIPHER_EncryptBytes](#CIPHER_EncryptBytes) or [CIPHER_DecryptBytes](#CIPHER_DecryptBytes) instead.

### VBA/VB6 Syntax

`Public Declare Function CIPHER_Bytes Lib "diCrPKI.dll" 
(ByVal fEncrypt As Long, ByRef lpOutput As Byte, ByRef lpData As Byte, ByVal nDataLen As Long, 
ByRef lpKey As Byte, ByRef lpIV As Byte, 
ByVal strAlgAndMode As String, ByVal nOptions As Long) As Long`

`nRet = CIPHER_Bytes(fEncrypt, lpOutput(0), lpData(0), nDataLen, lpKey(0), 
lpIV(0), strAlgAndMode, nOptions) ' Note the "(0)" after the byte array parameters`

### C/C++ Syntax

`long __stdcall CIPHER_Bytes(long fEncrypt, unsigned char *lpOutput, const unsigned char *lpData, long nDataLen, const unsigned char *lpKey, const unsigned char *lpIV, const char *szAlgAndMode, long nOptions);`

### Parameters

*fEncrypt*
:   [in] direction flag: 
set as `ENCRYPT` (True) to encrypt or `DECRYPT` (False) to decrypt.

*lpOutput*
:   [out] array of sufficient length to receive the output.

*lpData*
:   [in] array containing the input data.

*nDataLen*
:   [in] specifying the length of the input data in bytes.

*lpKey*
:   [in] array containing the key.

*lpIV*
:   [in] containing the
initialization vector (IV), or zero (0) for ECB mode.

*szAlgAndMode*
:   [in] containing the block cipher algorithm and mode
(see [Specifying the algorithm and mode for generic block cipher functions](#cipheralgmode)).

*nOptions*
:   [in] option flags.

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

[Cipher.Encrypt Method](#M_Cipher_Encrypt_ByteByteByteCipherAlgorithmMode) (Byte[], Byte[], Byte[], CipherAlgorithm, Mode)  

[Cipher.Decrypt Method](#M_Cipher_Decrypt_ByteByteByteCipherAlgorithmMode) (Byte[], Byte[], Byte[], CipherAlgorithm, Mode)  

### Remarks

The algorithm and mode must be specified using either the *szAlgAndMode* or *nOptions* parameter 
(see [Specifying the algorithm and mode for generic block cipher functions](#cipheralgmode)).

The length of key *lpKey* must be *exactly* the required key size, 
and the length of the IV, if required, *exactly* the block size.
See [Valid key and block sizes](#blockciphersizes).

**Important:** The output array *lpOutput* must be at least *nDataLen* bytes long.
*lpOutput* and *lpData* may be the same. 

For ECB and CBC modes, the length of the input data *lpInput* *must* be an exact multiple
of the block size otherwise a `BAD_LENGTH_ERROR` error will result.
It is the responsibility of the user to provide suitable padding before encrypting in those modes
and to remove any padding after decrypting.

### Example

Note that we convert the input data from hex strings to byte arrays in this example just for convenience 
so we can quickly demonstrate how the function works.
In practice, since you are using the "Bytes" function, we assume your input data would already be in byte array form.
If all your data strings are already in hex string format and you want the output in hex, then use 
[CIPHER_Hex](#CIPHER_Hex) instead.

```

Dim nRet As Long
Dim strOutput As String
Dim strInput As String
Dim sCorrect As String
Dim abKey()  As Byte
Dim abInitV() As Byte
Dim abResult() As Byte
Dim abData() As Byte
Dim abCheck() As Byte
Dim nDataLen As Long

' Set up input in byte arrays
strInput = "Now is the time for all good men"
sCorrect = "C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E177"
abKey = cnvBytesFromHexStr("0123456789ABCDEFF0E1D2C3B4A59687")
abInitV = cnvBytesFromHexStr("FEDCBA9876543210FEDCBA9876543210")
abData = StrConv(strInput, vbFromUnicode)
nDataLen = UBound(abData) - LBound(abData) + 1

' Pre-dimension output array
ReDim abResult(nDataLen - 1)

Debug.Print "KY=" & cnvHexStrFromBytes(abKey)
Debug.Print "IV=" & cnvHexStrFromBytes(abInitV)
Debug.Print "PT=" & strInput
Debug.Print "PT=" & cnvHexStrFromBytes(abData)
' Encrypt in one-off process (abResult <-- abData)
nRet = CIPHER_Bytes(ENCRYPT, abResult(0), abData(0), nDataLen, _
    abKey(0), abInitV(0), "aes128-cbc", 0)
Debug.Print "CIPHER_Bytes(ENCRYPT) returns " & nRet
Debug.Print "CT=" & cnvHexStrFromBytes(abResult)
Debug.Print "OK=" & sCorrect

' Now decrypt back (abCheck <-- abResult)
ReDim abCheck(nDataLen - 1)
nRet = CIPHER_Bytes(DECRYPT, abCheck(0), abResult(0), nDataLen, _
    abKey(0), abInitV(0), "", PKI_BC_AES128 + PKI_MODE_CBC)
Debug.Print "CIPHER_Bytes(DECRYPT) returns " & nRet
' And decode back from a byte array into a string
Debug.Print "P'=" & cnvHexStrFromBytes(abCheck)
strOutput = StrConv(abCheck(), vbUnicode)
Debug.Print "P'=" & strOutput

```

This should result in output as follows:

```

KY=0123456789ABCDEFF0E1D2C3B4A59687
IV=FEDCBA9876543210FEDCBA9876543210
PT=Now is the time for all good men
PT=4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E
CIPHER_Bytes(ENCRYPT) returns 0
CT=C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E177
OK=C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E177
CIPHER_Bytes(DECRYPT) returns 0
P'=4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E
P'=Now is the time for all good men

```

### See Also

[CIPHER_Hex](#CIPHER_Hex)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CIPHER_DecryptAEAD"></a>CIPHER_DecryptAEAD
-------------------------------------------------

Decrypt data using an authenticated encryption algorithm.

### VBA/VB6 Syntax

`Public Declare Function CIPHER_DecryptAEAD Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByRef lpInput As Byte, ByVal nInputLen As Long, ByRef lpKey As Byte, ByVal nKeyLen As Long, ByRef lpIV As Byte, ByVal nIvLen As Long, ByRef lpAAD As Byte, ByVal nAadLen As Long, ByVal nOptions As Long) As Long`

`nRet = CIPHER_DecryptAEAD(lpOutput(0), nOutBytes, lpInput(0), nInputLen, lpKey(0), nKeylen, lpIV(0), nIvLen, lpAAD(0), nAadLen, nOptions)`

### C/C++ Syntax

`long __stdcall CIPHER_DecryptAEAD(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpInput, long nInputLen, const unsigned char *lpKey, long nKeyLen, const unsigned char *lpIV, long nIvLen, const unsigned char *lpAAD, long nAadLen, long nOptions);`

### Parameters

*lpOutput*
:   [out] array of sufficient length to receive the output.

*nOutBytes*
:   [in] length of the output buffer in bytes.

*lpInput*
:   [in] array containing the input data.

*nInputLen*
:   [in] length of the input data in bytes.

*lpKey*
:   [in] array containing the key.

*nKeyLen*
:   [in] length of the key in bytes.

*lpIV*
:   [in] initialization vector (IV), a.k.a. nonce, if not provided in input.

*nIvLen*
:   [in] length of the IV in bytes.

*lpAAD*
:   [in] additional authenticated data (AAD)

*nAadLen*
:   [in] length of the AAD in bytes.

*nOptions*
:   [in] option flags. Must be one of:  

`PKI_AEAD_AES_128_GCM` to use `AEAD_AES_128_GCM` authenticated encryption algorithm from RFC 5116  

`PKI_AEAD_AES_256_GCM` to use `AEAD_AES_256_GCM` authenticated encryption algorithm from RFC 5116  

`PKI_AEAD_AES_192_GCM` to use the `AES-192-GCM` authenticated encryption algorithm in the same manner  

`PKI_AEAD_CHACHA20_POLY1305` to use the AEAD_CHACHA20_POLY1305 authenticated encryption algorithm (RFC8439)  

and optionally add  

`PKI_IV_PREFIX` to expect the IV to be prepended at the start of the input.

### Returns (VBA/C)

If successful, the return value is the number of bytes required in the output;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cipherDecryptAEAD`](#VB_cipherDecryptAEAD) (lpInput() As Byte, lpKey() As Byte, lpIV() As Byte, lpAAD() As Byte, nOptions As Long) As Byte()

### .NET Equivalent

[Cipher.DecryptAEAD Method](#M_Cipher_DecryptAEAD_ByteByteByteAeadAlgorithm) (Byte[], Byte[], Byte[], AeadAlgorithm)  

[Cipher.DecryptAEAD Method](#M_Cipher_DecryptAEAD_ByteByteByteByteAeadAlgorithmCipher_Opts) (Byte[], Byte[], Byte[], Byte[], AeadAlgorithm, Cipher.Opts)  

### C++ (STL) Equivalent

static bvec_t [dipki::Cipher::DecryptAEAD](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#a5c29247a4f848796ab7f832391eaa781 "External link") (const bvec_t &input, const bvec_t &key, const bvec_t &iv, AeadAlg aeadAlg, Opts opts=Opts::None, const bvec_t &aad=bvec_t())

### Python Equivalent

static [Cipher.decrypt_aead](https://cryptosys.net/pki/pydocpki/class-stubs/Cipher.html#cryptosyspki.Cipher.decrypt_aead "External link")(data, key, iv, aeadalg, aad=None, opts=Opts.DEFAULT)

### Remarks

The input is expected to be the ciphertext with a 16-byte tag appended `ciphertext||Tag`, or, if the `PKI_IV_PREFIX` option is set, 
then the same but with the 12-byte IV prepended `IV||ciphertext||Tag`, where `||` denotes concatenation.
If the IV is not prepended to the input, then it must be provided in the *lpIV* argument.
Note that the term "IV" is used here to mean exactly the same as "nonce".

The length of key *lpKey* must be *exactly* the required key size in bytes:
16 for `PKI_AEAD_AES_128_GCM`, 24 for `PKI_AEAD_AES_192_GCM`, or 32 for `PKI_AEAD_AES_256_GCM`.
It is an error if a `PKI_AEAD_` option is not provided in the *nOptions* argument.
In all cases the IV *must* be exactly 12 bytes (96 bits) and the tag *must* be exactly 16 bytes (128 bits).
If additional authentication data (AAD) was provided during encryption then the exact same AAD data must be provided here.

If *nOutBytes* is set to zero or *lpOutput* set to 0 (or `NULL` in C or `ByVal 0&` in VBA), 
the required number of bytes will be returned. 
This will be either exactly 16 bytes shorter than the length of the input, or exactly 28 bytes shorter if the `PKI_IV_PREFIX` option is used.

The output buffer *lpOutput* **must not** be the same as or overlap with the input *lpInput*.

### Example (VBA core function)

```

Dim key() As Byte
Dim iv() As Byte
Dim pt() As Byte
Dim ct() As Byte
Dim strOK As String
Dim ptlen As Long
Dim ctlen As Long
Dim keylen As Long
Dim ivlen As Long

' GCM Test Case #03 (AES-128)
key = cnvBytesFromHexStr("feffe9928665731c6d6a8f9467308308")
iv = cnvBytesFromHexStr("cafebabefacedbaddecaf888")
ct = cnvBytesFromHexStr("42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f59854d5c2af327cd64a62cf35abd2ba6fab4")
strOK = "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255"
keylen = UBound(key) + 1
ivlen = UBound(iv) + 1
ctlen = UBound(ct) + 1
Debug.Print "KY=" & cnvHexStrFromBytes(key)
Debug.Print "IV=" & cnvHexStrFromBytes(iv)
Debug.Print "CT=" & cnvHexStrFromBytes(ct)

' 1. Find out required output length
ptlen = CIPHER_DecryptAEAD(ByVal 0&, 0, ct(0), ctlen, key(0), keylen, iv(0), ivlen, ByVal 0&, 0, PKI_AEAD_AES_128_GCM)
Debug.Print "CIPHER_DecryptAEAD returns " & ptlen
' 1a. Cope with error
If (ptlen < 0) Then
    Debug.Print pkiErrorLookup(ptlen)
    Exit Sub
End If
' 2. Allocate the output buffer, coping with possible zero-length output, then decrypt
pt = vbNullString   ' Default empty array
If ptlen > 0 Then
    ReDim pt(ptlen - 1)
    ptlen = CIPHER_DecryptAEAD(pt(0), ptlen, ct(0), ctlen, key(0), keylen, iv(0), ivlen, ByVal 0&, 0, PKI_AEAD_AES_128_GCM)
End If
Debug.Print "PT=" & cnvHexStrFromBytes(pt)
Debug.Print "OK=" & strOK

```

This should result in output as follows:

```

KY=FEFFE9928665731C6D6A8F9467308308
IV=CAFEBABEFACEDBADDECAF888
CT=42831EC2217774244B7221B784D0D49CE3AA212F2C02A4E035C17E2329ACA12E21D514B25466931C7D8F6A5AAC84AA051BA30B396A0AAC973D58E091473F59854D5C2AF327CD64A62CF35ABD2BA6FAB4
CIPHER_DecryptAEAD returns 64
PT=D9313225F88406E5A55909C5AFF5269A86A7A9531534F7DA2E4C303D8A318A721C3C0C95956809532FCF0E2449A6B525B16AEDF5AA0DE657BA637B391AAFD255
OK=d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255

```

### Example (VBA wrapper function)

```

Dim key() As Byte
Dim iv() As Byte
Dim pt() As Byte
Dim ct() As Byte
Dim strOK As String
Dim ptlen As Long
Dim ctlen As Long
Dim keylen As Long
Dim ivlen As Long

' GCM Test Case #03 (AES-128)
key = cnvBytesFromHexStr("feffe9928665731c6d6a8f9467308308")
iv = cnvBytesFromHexStr("cafebabefacedbaddecaf888")
ct = cnvBytesFromHexStr("42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f59854d5c2af327cd64a62cf35abd2ba6fab4")
strOK = "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255"
keylen = UBound(key) + 1
ivlen = UBound(iv) + 1
ctlen = UBound(ct) + 1
Debug.Print "KY=" & cnvHexStrFromBytes(key)
Debug.Print "IV=" & cnvHexStrFromBytes(iv)
Debug.Print "CT=" & cnvHexStrFromBytes(ct)

' 1. Find out required output length
ptlen = CIPHER_DecryptAEAD(ByVal 0&, 0, ct(0), ctlen, key(0), keylen, iv(0), ivlen, ByVal 0&, 0, PKI_AEAD_AES_128_GCM)
Debug.Print "CIPHER_DecryptAEAD returns " & ptlen
' 1a. Cope with error
If (ptlen < 0) Then
    Debug.Print pkiErrorLookup(ptlen)
    Exit Sub
End If
' 2. Allocate the output buffer, coping with possible zero-length output, then decrypt
pt = vbNullString   ' Default empty array
If ptlen > 0 Then
    ReDim pt(ptlen - 1)
    ptlen = CIPHER_DecryptAEAD(pt(0), ptlen, ct(0), ctlen, key(0), keylen, iv(0), ivlen, ByVal 0&, 0, PKI_AEAD_AES_128_GCM)
End If
Debug.Print "PT=" & cnvHexStrFromBytes(pt)
Debug.Print "OK=" & strOK

' II.Using New wrapper
' Must dimension any optional empty byte array
Dim lpAAD() As Byte

pt = cipherDecryptAEAD(ct, key, iv, lpAAD, PKI_AEAD_AES_128_GCM)
Debug.Print "PT=" & cnvHexStrFromBytes(pt)

```

```

Dim key() As Byte
Dim iv() As Byte
Dim pt() As Byte
Dim ct() As Byte
Dim strOK As String

' GCM Test Case #03 (AES-128)
key = cnvBytesFromHexStr("feffe9928665731c6d6a8f9467308308")
iv = cnvBytesFromHexStr("cafebabefacedbaddecaf888")
ct = cnvBytesFromHexStr("42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f59854d5c2af327cd64a62cf35abd2ba6fab4")
strOK = "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255"
Dim lpAAD() As Byte ' Declare empty array for NULL input
pt = cipherDecryptAEAD(ct, key, iv, lpAAD, PKI_AEAD_AES_128_GCM)
Debug.Print "PT=" & cnvHexStrFromBytes(pt)
Debug.Print "OK=" & strOK
```

### See Also

[CIPHER_EncryptAEAD](#CIPHER_EncryptAEAD)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CIPHER_DecryptBytes"></a>CIPHER_DecryptBytes
---------------------------------------------------

Decrypt data in a byte array using the specified block cipher algorithm, mode and padding.
The key and initialization vector are passed as byte arrays.

### VBA/VB6 Syntax

`Public Declare Function CIPHER_DecryptBytes Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByRef lpInput As Byte, ByVal nInputLen As Long, ByRef lpKey As Byte, ByVal nKeyLen As Long, ByRef lpIV As Byte, ByVal nIvLen As Long, ByVal strAlgModePad As String, ByVal nOptions As Long) As Long`

`nRet = CIPHER_DecryptBytes(lpOutput(0), nOutBytes, lpInput(0), nInputLen, lpKey(0), nKeyLen, lpIV(0), nIvLen, strAlgModePad, nOptions)`

### C/C++ Syntax

`long __stdcall CIPHER_DecryptBytes(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpInput, long nInputLen, const unsigned char *lpKey, long nKeyLen, const unsigned char *lpIV, long nIvLen, const char *szAlgModePad, long nOptions);`

### Parameters

*lpOutput*
:   [out] array of sufficient length to receive the output (*must be at least as long as the input*, see ** in remarks)).

*nOutBytes*
:   [in] specifying the length of the output buffer in bytes.

*lpInput*
:   [in] array containing the input data.

*nInputLen*
:   [in] specifying the length of the input data in bytes.

*lpKey*
:   [in] array containing the key.

*nKeyLen*
:   [in] the length of the key in bytes.

*lpIV*
:   [in] containing the initialization vector (IV), or zero (0) or `NULL` for ECB mode.

*nIvLen*
:   [in] the length of the IV in bytes.

*szAlgModePad*
:   [in] containing the block cipher algorithm, mode and padding
(see [Specifying the algorithm, mode and padding for generic block cipher functions](#cipheralgmode)).

*nOptions*
:   [in] option flags:  

	Zero (0) for default options. Optionally add:  

`PKI_IV_PREFIX` to expect the IV to be prepended before the ciphertext in the input (ignored for ECB mode).

### Returns (VBA/C)

If successful, the return value is the number of bytes in or required in the output;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cipherDecryptBytes`](#VB_cipherDecryptBytes) (lpInput() As Byte, lpKey() As Byte, lpIV() As Byte, szAlgModePad As String, Optional nOptions As Long = 0) As Byte()

### .NET Equivalent

[Cipher.Decrypt Method](#M_Cipher_Decrypt_ByteByteByteCipherAlgorithmModePaddingCipher_Opts) (Byte[], Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)  

### C++ (STL) Equivalent

static bvec_t [dipki::Cipher::Decrypt](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#aefaac2005f99930eda0875a4e97c7a49 "External link") (const bvec_t &data, const bvec_t &key, const bvec_t &iv, Alg alg, Mode mode=Mode::ECB, Padding pad=Padding::Default, Opts opts=Opts::None)  

static bvec_t [dipki::Cipher::Decrypt](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#a11632dee81df1824241acb90ea1b73e8 "External link") (const bvec_t &data, const bvec_t &key, const bvec_t &iv, const std::string algModePad, Opts opts=Opts::None)

static [Cipher.decrypt_block](https://cryptosys.net/pki/pydocpki/class-stubs/Cipher.html#cryptosyspki.Cipher.decrypt_block "External link")(data, key, iv=None, alg=Alg.TDEA, mode=Mode.ECB)

### Python Equivalent

`static [Cipher.decrypt](https://cryptosys.net/pki/pydocpki/class-stubs/Cipher.html#cryptosyspki.Cipher.decrypt "External link")(data, key, iv=None, algmodepad='', alg=None, mode=Mode.ECB, pad=Pad.DEFAULT, opts=Opts.DEFAULT)`

static [Cipher.decrypt_block](https://cryptosys.net/pki/pydocpki/class-stubs/Cipher.html#cryptosyspki.Cipher.decrypt_block "External link")(data, key, iv=None, alg=Alg.TDEA, mode=Mode.ECB)

### Remarks

The algorithm/mode/padding must be specified using either the *szAlgModePad* string or *nOptions* parameter,
but not both
(see [Specifying the algorithm, mode and padding for generic block cipher functions](#cipheralgmode)).

The length of key *lpKey* must be *exactly* the required key size, 
and the length of the IV, if required, *exactly* the block size.
See [Valid key and block sizes](#blockciphersizes).

*[New in v12.3]* You can find the required output length in bytes by setting
*nOutBytes* to zero or *lpOutput* to 0 (or `NULL` in C or `ByVal 0&` in VBA).
For ECB and CBC cipher modes, the return value is now (as of *[v12.3]*) the exact length of plaintext *after* padding has been removed.

** For ECB and CBC cipher modes, any padding must be removed. To specify the length of *lpOutput* you can either
1. [ORIGINAL METHOD] specify the output length of *lpOutput* equal to the length of the input then truncate the result to the correct length.
2. [NEW in v12.3] do a first pass setting *nOutBytes* to zero or *lpOutput* to 0 or `NULL` to find the exact decrypted length.

See the examples below. In both cases you may need to cope with the special case where the encrypted output is the empty string, a zero-length byte array.

It is an error (`DECRYPT_ERROR`) if the padding bytes after decryption are not as expected according to the padding method specified.
If the cipher mode is ECB or CBC, it is an error (`BAD_LENGTH_ERROR`) 
if the length of the input is not an exact multiple of the block size.
The input buffer *lpInput* may point to the same location as the output buffer. 
If so, the input ciphertext data will be overwritten by the output (and the user must truncate to remove any padding bytes).

**Defaults:** If padding is not specified then the default padding method depends on the cipher mode: 
`pkcs5padding` will be used for ECB and CBC mode and `nopadding` for all other modes.
The default cipher mode is `ECB`. 
Thus `"aes128"` is the same as `"aes128/ecb/pkcs5padding"`.

### Examples

```

Dim key() As Byte
Dim iv() As Byte
Dim ct() As Byte
Dim ok() As Byte
Dim dt() As Byte
Dim ctlen As Long
Dim dtlen As Long
Dim keylen As Long
Dim ivlen As Long
Dim algstr As String

' INPUT for known test vector
algstr = "Aes128/CBC/OneAndZeroes"
Debug.Print algstr
key = cnvBytesFromHexStr("0123456789ABCDEFF0E1D2C3B4A59687")
iv = cnvBytesFromHexStr("FEDCBA9876543210FEDCBA9876543210")
keylen = UBound(key) + 1
ivlen = UBound(iv) + 1
Debug.Print ("KY=" & cnvHexStrFromBytes(key))
Debug.Print ("IV=" & cnvHexStrFromBytes(iv))
ct = cnvBytesFromHexStr("C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B")
ctlen = UBound(ct) + 1
Debug.Print ("CT=" & cnvHexStrFromBytes(ct))
' OK = "Now is the time for all good men to"
ok = cnvBytesFromHexStr("4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F")

' DECRYPT - OLD METHOD
Debug.Print "Decrypt - old method with truncation"
' 1. Set output buffer to same length as input (final output will always be shorter for CBC mode)
dtlen = ctlen
ReDim dt(dtlen - 1)
' 2. Perform decryption including padding into output buffer
dtlen = CIPHER_DecryptBytes(dt(0), dtlen, ct(0), ctlen, key(0), keylen, iv(0), ivlen, algstr, 0)
Debug.Print "CIPHER_DecryptBytes returns " & dtlen
Debug.Assert dtlen > 0
' 3. Re-dimension the output to the correct length
ReDim Preserve dt(dtlen - 1)

Debug.Print ("DT=" & cnvHexStrFromBytes(dt))
Debug.Print ("DT='" & StrConv(dt, vbUnicode) + "'")

' DECRYPT - NEW METHOD [v12.3]
Debug.Print "Decrypt - new method with exact length"
' 1. Find exact output length using null/zero-length output
dtlen = CIPHER_DecryptBytes(ByVal 0&, 0, ct(0), ctlen, key(0), keylen, iv(0), ivlen, algstr, 0)
Debug.Print "CIPHER_DecryptBytes(NULL) returns " & dtlen
Debug.Assert dtlen > 0
' 2. Dimension output buffer to exact length
ReDim dt(dtlen - 1)
' 3. Perform decryption - no need to truncate
dtlen = CIPHER_DecryptBytes(dt(0), dtlen, ct(0), ctlen, key(0), keylen, iv(0), ivlen, algstr, 0)
Debug.Print "CIPHER_DecryptBytes returns " & dtlen
Debug.Assert dtlen > 0

Debug.Print ("DT=" & cnvHexStrFromBytes(dt))
Debug.Print ("DT='" & StrConv(dt, vbUnicode) + "'")

Debug.Print "Check actual padding by decrypting with NoPadding..."
algstr = "Aes128/CBC/NoPadding"
Debug.Print algstr
dtlen = ctlen
ReDim dt(dtlen - 1)
dtlen = CIPHER_DecryptBytes(dt(0), dtlen, ct(0), ctlen, key(0), keylen, iv(0), ivlen, algstr, 0)
Debug.Print "CIPHER_DecryptBytes(NoPadding) returns " & dtlen
Debug.Print ("DT=" & cnvHexStrFromBytes(dt))

```

This should result in output as follows:

```

Aes128/CBC/OneAndZeroes
KY=0123456789ABCDEFF0E1D2C3B4A59687
IV=FEDCBA9876543210FEDCBA9876543210
CT=C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B
Decrypt - old method with truncation
CIPHER_DecryptBytes returns 35
DT=4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F
DT='Now is the time for all good men to'
Decrypt - new method with exact length
CIPHER_DecryptBytes(NULL) returns 35
CIPHER_DecryptBytes returns 35
DT=4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F
DT='Now is the time for all good men to'
Check actual padding by decrypting with NoPadding...
Aes128/CBC/NoPadding
CIPHER_DecryptBytes(NoPadding) returns 48
DT=4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F80000000000000000000000000

```

**Example 2:** showing use of `PKI_IV_PREFIX` to prepend the IV before the ciphertext in the output.

```

Dim strCipherValue As String
Dim strPlain As String
Dim pt() As Byte
Dim ptlen As Long
Dim ct() As Byte
Dim ctlen As Long
Dim key() As Byte
Dim keylen As Long
Dim iv() As Byte
Dim ivlen As Long
Dim nRet As Long
Dim strDT As String
Dim dt() As Byte
Dim dtlen As Long

' The plaintext to encrypt...
strPlain = "<encryptme>hello world</encryptme>"
Debug.Print "PT='" & strPlain & "'"

' We need this as a byte array...
pt = StrConv(strPlain, vbFromUnicode)
Debug.Print "HEX(PT)=" & cnvHexStrFromBytes(pt)
ptlen = UBound(pt) + 1
Debug.Print "Len(PT)=" & ptlen

' 128-bit AES key
' (Usually generated at random but here we use a fixed test one)
key = cnvBytesFromHexStr("6162636465666768696A6B6C6D6E6F70")
keylen = UBound(key) + 1
Debug.Print "HEX(KEY)=" & cnvHexStrFromBytes(key)

' Generate a random 128-bit IV for AES encryption
ivlen = PKI_BLK_AES_BYTES
ReDim iv(ivlen - 1)
nRet = RNG_Bytes(iv(0), ivlen, "", 0)
Debug.Print "HEX(IV)=" & cnvHexStrFromBytes(iv)

' Encrypt using AES-128 with IV prefixed to ciphertext

' How many bytes in the encrypted output?
ctlen = CIPHER_EncryptBytes(ByVal 0&, 0, pt(0), ptlen, key(0), keylen, iv(0), ivlen, "aes128/cbc/pkcs5", PKI_IV_PREFIX)
Debug.Print "Len(IV|CT)=" & ctlen
Debug.Assert (ctlen > 0)
' Allocate the buffer
ReDim ct(ctlen - 1)
' Encrypt to output buffer
ctlen = CIPHER_EncryptBytes(ct(0), ctlen, pt(0), ptlen, key(0), keylen, iv(0), ivlen, "aes128/cbc/pkcs5", PKI_IV_PREFIX)
Debug.Assert (ctlen > 0)
Debug.Print "IV|CT=" & cnvHexStrFromBytes(ct)

' Encode CT using base64
strCipherValue = cnvB64StrFromBytes(ct)

' Output the CipherValue element
' (Note this will be different each time)
Debug.Print "<CipherValue>" & strCipherValue & "</CipherValue>"

' ------------------------------------------
' PART 2 - decrypt the given ciphertext

Debug.Print
Debug.Print "DECRYPTING..."
' INPUT: strCipherValue, key
' Decode base64 to byte array
ct = cnvBytesFromB64Str(strCipherValue)
ctlen = UBound(ct) + 1
Debug.Print "IV|CT=" & cnvHexStrFromBytes(ct)
' Find decrypted output length - new behaviour in [v12.3] (previously needed to truncate)
dtlen = CIPHER_DecryptBytes(ByVal 0&, 0, ct(0), ctlen, key(0), keylen, ByVal 0&, 0, "aes128/cbc/pkcs5", PKI_IV_PREFIX)
Debug.Assert (dtlen > 0)
ReDim dt(dtlen - 1)
' Note we don't need to specify the IV: it is included in the prefix
dtlen = CIPHER_DecryptBytes(dt(0), dtlen, ct(0), ctlen, key(0), keylen, ByVal 0&, 0, "aes128/cbc/pkcs5", PKI_IV_PREFIX)
Debug.Print "Len(DT)=" & dtlen
Debug.Assert (dtlen >= 0)

Debug.Print "DT=" & cnvHexStrFromBytes(dt)
' Convert from bytes to string
strDT = StrConv(dt, vbUnicode)
Debug.Print "DT='" & strDT & "'"

```

```

PT='<encryptme>hello world</encryptme>'
HEX(PT)=3C656E63727970746D653E68656C6C6F20776F726C643C2F656E63727970746D653E
Len(PT)=34
HEX(KEY)=6162636465666768696A6B6C6D6E6F70
HEX(IV)=556DA05DF58DE51874B032768BA99A26
Len(IV|CT)=64
IV|CT=556DA05DF58DE51874B032768BA99A26884B6CD2045916D7F1D8D88E6BB8F5520C69479D352701BBBA2E67DE03DF0319B3C83EA90093AC6C77E4709A26B46E80
<CipherValue>VW2gXfWN5Rh0sDJ2i6maJohLbNIEWRbX8djYjmu49VIMaUedNScBu7ouZ94D3wMZs8g+qQCTrGx35HCaJrRugA==</CipherValue>

DECRYPTING...
IV|CT=556DA05DF58DE51874B032768BA99A26884B6CD2045916D7F1D8D88E6BB8F5520C69479D352701BBBA2E67DE03DF0319B3C83EA90093AC6C77E4709A26B46E80
Len(DT)=34
DT=3C656E63727970746D653E68656C6C6F20776F726C643C2F656E63727970746D653E
DT='<encryptme>hello world</encryptme>'

```

### Example (VBA wrapper function)

See example for VBA wrapper `cipherEncryptBytes` in [CIPHER_EncryptBytes](#CIPHER_EncryptBytes).

### See Also

[CIPHER_EncryptBytes](#CIPHER_EncryptBytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CIPHER_DecryptBytes2"></a>CIPHER_DecryptBytes2
-----------------------------------------------------

@deprecated use `[CIPHER_DecryptBytes](#CIPHER_DecryptBytes)`.

<a id="CIPHER_DecryptHex"></a>CIPHER_DecryptHex
-----------------------------------------------

Decrypt data using the specified block cipher algorithm, mode and padding. 
The input data, key and initialization vector are all represented as hexadecimal strings.

### VBA/VB6 Syntax

`Public Declare Function CIPHER_DecryptHex Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strInputHex As String, ByVal strKeyHex As String, ByVal strIvHex As String, ByVal strAlgModePad As String, ByVal nOptions As Long) As Long`

`nRet = CIPHER_DecryptHex(strOutput, nOutChars, strInputHex, strKeyHex, strIvHex, strAlgModePad, nOptions)`

### C/C++ Syntax

`long __stdcall CIPHER_DecryptHex(char *szOutput, long nOutChars, const char *szInputHex, const char *szKeyHex, const char *szIvHex, const char *szAlgModePad, long nOptions);`

### Parameters

*szOutput*
:   [out] string buffer of sufficient length to receive the output.

*nOutChars*
:   [in] maximum number of characters to be received.

*szInputHex*
:   [in] the input data in hex format.

*szKeyHex*
:   [in] the key in hex format.

*szIvHex*
:   [in] the initialization vector (IV) in hex format, ignored for ECB mode or if `PKI_IV_PREFIX` is used (use `""`).

*szAlgModePad*
:   [in] string specifying the block cipher algorithm, mode and padding
(see [Specifying the algorithm, mode and padding for generic block cipher functions](#cipheralgmode)).

*nOptions*
:   [in] option flags:  

	Zero (0) for default options. Optionally add:  

`PKI_IV_PREFIX` to expect the IV to be prepended before the ciphertext in the input (not applicable for ECB mode).

### Returns (VBA/C)

If successful, the return value is the number of characters in or required in the output;
otherwise it returns a nonzero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cipherDecryptHex`](#VB_cipherDecryptHex) (szInputHex As String, szKeyHex As String, szIvHex As String, szAlgModePad As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Cipher.Decrypt Method](#M_Cipher_Decrypt_StringStringStringCipherAlgorithmModePaddingCipher_Opts) (String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts)  

### Python Equivalent

static [Cipher.decrypt_hex](https://cryptosys.net/pki/pydocpki/class-stubs/Cipher.html#cryptosyspki.Cipher.decrypt_hex "External link")(datahex, keyhex, ivhex='', algmodepad='', alg=None, mode=Mode.ECB, pad=Pad.DEFAULT, opts=Opts.DEFAULT)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

This is the equivalent of [`CIPHER_DecryptBytes`](#CIPHER_DecryptBytes) with all parameters passed as hex-encoded strings instead of byte arrays.
It is similar to the [`CIPHER_Hex`](#CIPHER_Hex) function except this accepts variable-length input and copes with padding if required, as well as the option to prepend the IV to the ciphertext.

Any padding will be removed after decryption.

If the `PKI_IV_PREFIX` option is used, the IV will be expected prepended to the ciphertext in the input.

The algorithm/mode/padding must be specified using either the *szAlgModePad* string or *nOptions* parameter,
but not both
(see [Specifying the algorithm, mode and padding for generic block cipher functions](#cipheralgmode)).

It is an error (`BAD_PARAM_ERROR`) to pass the empty string `""` as input in *szInputHex*.
The output buffer *strOutput* should *not* be the same as the input *strInputHex*.

CAUTION: be aware of the special case where the output is the empty string `""` of length zero.

### Example (VBA core function)

```

Dim strKey As String
Dim strIV As String
Dim strPlain As String
Dim strCipher As String
Dim strOK As String
Dim strAlg As String
Dim nChars As Long

strAlg = "Aes128/CBC/OneAndZeroes"
Debug.Print strAlg
strKey = "0123456789ABCDEFF0E1D2C3B4A59687"
strIV = "FEDCBA9876543210FEDCBA9876543210"
Debug.Print "KY=" & strKey
Debug.Print "IV=" & strIV
strCipher = "C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B"
Debug.Print "CT=" & strCipher
' Correct result
strOK = "4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F"

' 1. Find out how long an output buffer we need
nChars = CIPHER_DecryptHex(vbNullString, 0, strCipher, strKey, strIV, strAlg, 0)
Debug.Print "CIPHER_DecryptHex returns " & nChars
Debug.Assert nChars > 0
' 2. Allocate the buffer
strPlain = String(nChars, " ")
' 3. Decrypt to output buffer
nChars = CIPHER_DecryptHex(strPlain, nChars, strCipher, strKey, strIV, strAlg, 0)

Debug.Print "PT=" & strPlain
Debug.Print "OK=" & strOK

' PART 2 - CT includes IV prefix
strCipher = "FEDCBA9876543210FEDCBA9876543210C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B"
Debug.Print "IV||CT=" & strCipher
nChars = CIPHER_DecryptHex(vbNullString, 0, strCipher, strKey, strIV, strAlg, PKI_IV_PREFIX)
Debug.Print "CIPHER_DecryptHex(PKI_IV_PREFIX) returns " & nChars
Debug.Assert nChars > 0
strPlain = String(nChars, " ")
nChars = CIPHER_DecryptHex(strPlain, nChars, strCipher, strKey, strIV, strAlg, PKI_IV_PREFIX)

Debug.Print "PT=" & strPlain
Debug.Print "PT='" & cnvStringFromHexStr(strPlain) & "'"

```

This should result in output as follows:

```

Aes128/CBC/OneAndZeroes
KY=0123456789ABCDEFF0E1D2C3B4A59687
IV=FEDCBA9876543210FEDCBA9876543210
CT=C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B
CIPHER_DecryptHex returns 70
PT=4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F
OK=4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F
IV||CT=FEDCBA9876543210FEDCBA9876543210C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B
CIPHER_DecryptHex(PKI_IV_PREFIX) returns 70
PT=4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F
PT='Now is the time for all good men to'

```

### Example (VBA wrapper function)

```

Dim strKeyHex As String
Dim strIvHex As String
Dim strPlainHex As String
Dim strCipherHex As String
strKeyHex = "0123456789ABCDEFF0E1D2C3B4A59687"
strIvHex = "FEDCBA9876543210FEDCBA9876543210"
strCipherHex = "C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B"
strPlainHex = cipherDecryptHex(strCipherHex, strKeyHex, strIvHex, "Aes128/CBC/OneAndZeroes")
Debug.Print "PT=" & strPlainHex
Debug.Print "PT='" & cnvStringFromHexStr(strPlainHex) & "'"

```

### See Also

[CIPHER_EncryptHex](#CIPHER_EncryptHex)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CIPHER_EncryptAEAD"></a>CIPHER_EncryptAEAD
-------------------------------------------------

Encrypt data using an authenticated encryption algorithm.

### VBA/VB6 Syntax

`Public Declare Function CIPHER_EncryptAEAD Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByRef lpInput As Byte, ByVal nInputLen As Long, ByRef lpKey As Byte, ByVal nKeyLen As Long, ByRef lpIV As Byte, ByVal nIvLen As Long, ByRef lpAAD As Byte, ByVal nAadLen As Long, ByVal nOptions As Long) As Long`

`nRet = CIPHER_EncryptAEAD(lpOutput(0), nOutBytes, lpInput(0), nInputLen, lpKey(0), nKeylen, lpIV(0), nIvLen, lpAAD(0), nAadLen, nOptions)`

### C/C++ Syntax

`long __stdcall CIPHER_EncryptAEAD(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpInput, long nInputLen, const unsigned char *lpKey, long nKeyLen, const unsigned char *lpIV, long nIvLen, const unsigned char *lpAAD, long nAadLen, long nOptions);`

### Parameters

*lpOutput*
:   [out] array of sufficient length to receive the output.

*nOutBytes*
:   [in] length of the output buffer in bytes.

*lpInput*
:   [in] array containing the input data.

*nInputLen*
:   [in] length of the input data in bytes.

*lpKey*
:   [in] array containing the key.

*nKeyLen*
:   [in] length of the key in bytes.

*lpIV*
:   [in] (required) initialization vector (IV), a.k.a. nonce.

*nIvLen*
:   [in] length of the IV in bytes (must be exactly 12).

*lpAAD*
:   [in] (optional) additional authenticated data (AAD)

*nAadLen*
:   [in] length of the AAD in bytes.

*nOptions*
:   [in] option flags. Must be one of:  

`PKI_AEAD_AES_128_GCM` to use `AEAD_AES_128_GCM` authenticated encryption algorithm from RFC 5116  

`PKI_AEAD_AES_256_GCM` to use `AEAD_AES_256_GCM` authenticated encryption algorithm from RFC 5116  

`PKI_AEAD_AES_192_GCM` to use the `AES-192-GCM` authenticated encryption algorithm in the same manner  

`PKI_AEAD_CHACHA20_POLY1305` to use the AEAD_CHACHA20_POLY1305 authenticated encryption algorithm (RFC 8439)  

and optionally add  

`PKI_IV_PREFIX` to prepend the IV before the ciphertext in the output.

### Returns (VBA/C)

If successful, the return value is the number of bytes required in the output;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cipherEncryptAEAD`](#VB_cipherEncryptAEAD) (lpInput() As Byte, lpKey() As Byte, lpIV() As Byte, lpAAD() As Byte, nOptions As Long) As Byte()

### .NET Equivalent

[Cipher.EncryptAEAD Method](#M_Cipher_EncryptAEAD_ByteByteByteAeadAlgorithm) (Byte[], Byte[], Byte[], AeadAlgorithm)  

[Cipher.EncryptAEAD Method](#M_Cipher_EncryptAEAD_ByteByteByteByteAeadAlgorithmCipher_Opts) (Byte[], Byte[], Byte[], Byte[], AeadAlgorithm, Cipher.Opts)  

### C++ (STL) Equivalent

static bvec_t [dipki::Cipher::EncryptAEAD](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#abb21e6a14b2bcd15317f952eca4ab581 "External link") (const bvec_t &input, const bvec_t &key, const bvec_t &iv, AeadAlg aeadAlg, Opts opts=Opts::None, const bvec_t &aad=bvec_t())

### Python Equivalent

static [Cipher.encrypt_aead](https://cryptosys.net/pki/pydocpki/class-stubs/Cipher.html#cryptosyspki.Cipher.encrypt_aead "External link")(data, key, iv, aeadalg, aad=None, opts=Opts.DEFAULT)

### Remarks

This function carries out [authenticated encryption using AES-GCM](#authencryptionaad).
In this implementation, the function  
*must* have a fixed-length nonce (IV) of exactly 12 bytes (96 bits) and only creates a fixed-length tag of exactly 16 bytes (128 bits). 
There is no option to use different lengths for the IV or tag.
The tag is automatically appended to the output of the encryption operation. 
The IV may optionally be prepended to the output using the `PKI_IV_PREFIX` option flag. 
Note that the term "IV" is used here to mean exactly the same as "nonce".

The length of key *lpKey* must be *exactly* the required key size in bytes: 16 for `PKI_AEAD_AES_128_GCM`, 24 for `PKI_AEAD_AES_192_GCM`, or 32 for `PKI_AEAD_AES_256_GCM`.
It is an error if a `PKI_AEAD_` option is not provided in the *nOptions* argument.
The length of the IV *must* be exactly 12 bytes.
The user is responsible for providing a unique IV each time the same key is used.
Be aware it is a serious security risk if the same IV and key are used to encrypt different plaintexts.

If *nOutBytes* is set to zero or *lpOutput* set to 0 (or `NULL` in C or `ByVal 0&` in VBA), 
the required number of bytes will be returned. 
This will be either exactly 16 bytes longer than the length of the input, or exactly 28 bytes longer if the `PKI_IV_PREFIX` option is used.

The output buffer *lpOutput* **must not** be the same as or overlap with the input *lpInput*.

### Example (VBA core function)

```

Dim key() As Byte
Dim iv() As Byte
Dim pt() As Byte
Dim ct() As Byte
Dim strOK As String
Dim ptlen As Long
Dim ctlen As Long
Dim keylen As Long
Dim ivlen As Long

' GCM Test Case #03 (AES-128)
key = cnvBytesFromHexStr("feffe9928665731c6d6a8f9467308308")
iv = cnvBytesFromHexStr("cafebabefacedbaddecaf888")
pt = cnvBytesFromHexStr("d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255")
strOK = "42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f59854d5c2af327cd64a62cf35abd2ba6fab4"
keylen = UBound(key) + 1
ivlen = UBound(iv) + 1
ptlen = UBound(pt) + 1
Debug.Print "KY=" & cnvHexStrFromBytes(key)
Debug.Print "IV=" & cnvHexStrFromBytes(iv)
Debug.Print "PT=" & cnvHexStrFromBytes(pt)
' 1. Find out how long an output buffer we need
ctlen = CIPHER_EncryptAEAD(ByVal 0&, 0, pt(0), ptlen, key(0), keylen, iv(0), ivlen, ByVal 0&, 0, PKI_AEAD_AES_128_GCM)
Debug.Print "CIPHER_EncryptAEAD returns " & ctlen
Debug.Assert ctlen > 0
' 2. Allocate the buffer
ReDim ct(ctlen - 1)
' 3. Encrypt to output buffer (NB tag is appended to the end)
ctlen = CIPHER_EncryptAEAD(ct(0), ctlen, pt(0), ptlen, key(0), keylen, iv(0), ivlen, ByVal 0&, 0, PKI_AEAD_AES_128_GCM)

Debug.Print "CT=" & cnvHexStrFromBytes(ct)
Debug.Print "OK=" & strOK
    
' Repeat but prepend IV to output
ctlen = CIPHER_EncryptAEAD(ByVal 0&, 0, pt(0), ptlen, key(0), keylen, iv(0), ivlen, ByVal 0&, 0, PKI_AEAD_AES_128_GCM Or PKI_IV_PREFIX)
Debug.Print "CIPHER_EncryptAEAD returns " & ctlen
Debug.Assert ctlen > 0
ReDim ct(ctlen - 1)
ctlen = CIPHER_EncryptAEAD(ct(0), ctlen, pt(0), ptlen, key(0), keylen, iv(0), ivlen, ByVal 0&, 0, PKI_AEAD_AES_128_GCM Or PKI_IV_PREFIX)

Debug.Print "IV|CT=" & cnvHexStrFromBytes(ct)

```

This should result in output as follows:

```

KY=FEFFE9928665731C6D6A8F9467308308
IV=CAFEBABEFACEDBADDECAF888
PT=D9313225F88406E5A55909C5AFF5269A86A7A9531534F7DA2E4C303D8A318A721C3C0C95956809532FCF0E2449A6B525B16AEDF5AA0DE657BA637B391AAFD255
CIPHER_EncryptAEAD returns 80
CT=42831EC2217774244B7221B784D0D49CE3AA212F2C02A4E035C17E2329ACA12E21D514B25466931C7D8F6A5AAC84AA051BA30B396A0AAC973D58E091473F59854D5C2AF327CD64A62CF35ABD2BA6FAB4
OK=42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f59854d5c2af327cd64a62cf35abd2ba6fab4
CIPHER_EncryptAEAD returns 92
IV|CT=CAFEBABEFACEDBADDECAF88842831EC2217774244B7221B784D0D49CE3AA212F2C02A4E035C17E2329ACA12E21D514B25466931C7D8F6A5AAC84AA051BA30B396A0AAC973D58E091473F59854D5C2AF327CD64A62CF35ABD2BA6FAB4

```

### Example (VBA wrapper function)

```

Dim key() As Byte
Dim iv() As Byte
Dim pt() As Byte
Dim ct() As Byte
Dim lpDummy() As Byte
' GCM Test Case #03 (AES-128)
key = cnvBytesFromHexStr("feffe9928665731c6d6a8f9467308308")
iv = cnvBytesFromHexStr("cafebabefacedbaddecaf888")
pt = cnvBytesFromHexStr("d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255")
ct = cipherEncryptAEAD(pt, key, iv, lpDummy, PKI_AEAD_AES_128_GCM Or PKI_IV_PREFIX)
Debug.Print "IV|CT=" & cnvHexStrFromBytes(ct)
Debug.Print "OK=   " & _
    "CAFEBABEFACEDBADDECAF888" & _
"42831EC2217774244B7221B784D0D49CE3AA212F2C02A4E035C17E2329ACA12E21D514B25466931C7D8F6A5AAC84AA051BA30B396A0AAC973D58E091473F59854D5C2AF327CD64A62CF35ABD2BA6FAB4"

```

### See Also

[CIPHER_DecryptAEAD](#CIPHER_DecryptAEAD)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CIPHER_EncryptBytes"></a>CIPHER_EncryptBytes
---------------------------------------------------

Encrypt data in a byte array using the specified block cipher algorithm, mode and padding.
The key and initialization vector are passed as byte arrays.

### VBA/VB6 Syntax

`Public Declare Function CIPHER_EncryptBytes Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByRef lpInput As Byte, ByVal nInputLen As Long, ByRef lpKey As Byte, ByVal nKeyLen As Long, ByRef lpIV As Byte, ByVal nIvLen As Long, ByVal strAlgModePad As String, ByVal nOptions As Long) As Long`

`nRet = CIPHER_EncryptBytes(lpOutput(0), nOutBytes, lpInput(0), nInputLen, lpKey(0), nKeylen, lpIV(0), nIvLen, strAlgModePad, nOptions)`

### C/C++ Syntax

`long __stdcall CIPHER_EncryptBytes(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpInput, long nInputLen, const unsigned char *lpKey, long nKeyLen, const unsigned char *lpIV, long nIvLen, const char *szAlgModePad, long nOptions);`

### Parameters

*lpOutput*
:   [out] array of sufficient length to receive the output.

*nOutBytes*
:   [in] specifying the length of the output buffer in bytes.

*lpInput*
:   [in] array containing the input data.

*nInputLen*
:   [in] specifying the length of the input data in bytes.

*lpKey*
:   [in] array containing the key.

*nKeyLen*
:   [in] the length of the key in bytes.

*lpIV*
:   [in] containing the initialization vector (IV), or zero (0) or `NULL` for ECB mode.

*nIvLen*
:   [in] the length of the IV in bytes.

*szAlgModePad*
:   [in] containing the block cipher algorithm, mode and padding
(see [Specifying the algorithm, mode and padding for generic block cipher functions](#cipheralgmode)).

*nOptions*
:   [in] option flags:  

	Zero (0) for default options. Optionally add:  

`PKI_IV_PREFIX` to prepend the IV before the ciphertext in the output (ignored for ECB mode).

### Returns (VBA/C)

If successful, the return value is the number of bytes required in the output;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cipherEncryptBytes`](#VB_cipherEncryptBytes) (lpInput() As Byte, lpKey() As Byte, lpIV() As Byte, szAlgModePad As String, Optional nOptions As Long = 0) As Byte()

### .NET Equivalent

[Cipher.Encrypt Method](#M_Cipher_Encrypt_ByteByteByteCipherAlgorithmModePaddingCipher_Opts) (Byte[], Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)  

### C++ (STL) Equivalent

static bvec_t [dipki::Cipher::Encrypt](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#a1b78e8753a8eee4d335cc830b2337edd "External link") (const bvec_t &data, const bvec_t &key, const bvec_t &iv, Alg alg, Mode mode=Mode::ECB, Padding pad=Padding::Default, Opts opts=Opts::None)  

static bvec_t [dipki::Cipher::Encrypt](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#ae84957081fede5e2934fb68d1d60b9ba "External link") (const bvec_t &data, const bvec_t &key, const bvec_t &iv, const std::string algModePad, Opts opts=Opts::None)

static [Cipher.encrypt_block](https://cryptosys.net/pki/pydocpki/class-stubs/Cipher.html#cryptosyspki.Cipher.encrypt_block "External link")(data, key, iv=None, alg=Alg.TDEA, mode=Mode.ECB)

### Python Equivalent

`static [Cipher.encrypt](https://cryptosys.net/pki/pydocpki/class-stubs/Cipher.html#cryptosyspki.Cipher.encrypt "External link")(data, key, iv=None, algmodepad='', alg=None, mode=Mode.ECB, pad=Pad.DEFAULT, opts=Opts.DEFAULT)`

static [Cipher.encrypt_block](https://cryptosys.net/pki/pydocpki/class-stubs/Cipher.html#cryptosyspki.Cipher.encrypt_block "External link")(data, key, iv=None, alg=Alg.TDEA, mode=Mode.ECB)

### Remarks

Padding is added as specified to the input before encryption.
The user must allocate an output buffer of the required length, which will always be at least as long as the input,
or longer if padding is to be added.

The algorithm/mode/padding must be specified using either the *szAlgModePad* string or *nOptions* parameter,
but not both
(see [Specifying the algorithm, mode and padding for generic block cipher functions](#cipheralgmode)).

The length of key *lpKey* must be *exactly* the required key size, 
and the length of the IV, if required, *exactly* the block size.
See [Valid key and block sizes](#blockciphersizes).

If *nOutBytes* is set to zero or *lpOutput* set to 0 (or `NULL` in C or `ByVal 0&` in VBA), 
the required number of bytes will be returned.
If the `NoPadding` option is specified, the required output length will be the same as the input.

**Defaults:** If padding is not specified then the default padding method depends on the cipher mode: 
`pkcs5padding` will be used for ECB and CBC mode and `nopadding` for all other modes.
The default cipher mode is `ECB`. 
Thus `"aes128"` is the same as `"aes128/ecb/pkcs5padding"`.

Note that padding is only needed for ECB or CBC mode where the input length is not a multiple of the block size.
It is an error (`BAD_LENGTH_ERROR`) to specify `NoPadding` with ECB or CBC mode if the length of the input 
is not an exact multiple of the block size.

The padding option is ignored for CTR, OFB and CFB modes, which do not need padding.
The default `nopadding` is *always* used for these modes regardless of what is specified 
(so just use the default, e.g. `"aes128/ctr"`).

*[New in v12.3]*
Use the `PKI_IV_PREFIX` to prepend the IV before the ciphertext in the output.
This will add the IV before the ciphertext in the form `IV||CT`.
This is the scheme used with block ciphers in XML encryption (see section 5.2 of [[XMLENC](#XMLENC)])
where they use the phrase "The resulting cipher text is prefixed by the IV."
It is the responsibility of the receiver to parse this data to recover the IV.

### Example (VBA core function)

```

Dim key() As Byte
Dim iv() As Byte
Dim pt() As Byte
Dim ct() As Byte
Dim ok() As Byte
Dim ptlen As Long
Dim ctlen As Long
Dim keylen As Long
Dim ivlen As Long
Dim algstr As String

algstr = "Aes128/CBC/OneAndZeroes"
Debug.Print algstr
key = cnvBytesFromHexStr("0123456789ABCDEFF0E1D2C3B4A59687")
iv = cnvBytesFromHexStr("FEDCBA9876543210FEDCBA9876543210")
keylen = UBound(key) + 1
ivlen = UBound(iv) + 1
Debug.Print "KY=" & cnvHexStrFromBytes(key)
Debug.Print "IV=" & cnvHexStrFromBytes(iv)
' "Now is the time for all good men to"
pt = cnvBytesFromHexStr("4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F")
ptlen = UBound(pt) + 1
' Correct result
ok = cnvBytesFromHexStr("C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B")
Debug.Print ("PT=" & cnvHexStrFromBytes(pt))
Debug.Print ("PT='" & StrConv(pt, vbUnicode) + "'")
' 1. Find out how long an output buffer we need
ctlen = CIPHER_EncryptBytes(0, 0, pt(0), ptlen, key(0), keylen, iv(0), ivlen, algstr, 0)
Debug.Print "CIPHER_EncryptBytes returns " & ctlen
' 2. Allocate the buffer
ReDim ct(ctlen - 1)
' 3. Encrypt to output buffer
ctlen = CIPHER_EncryptBytes(ct(0), ctlen, pt(0), ptlen, key(0), keylen, iv(0), ivlen, algstr, 0)

Debug.Print "CT=" & cnvHexStrFromBytes(ct)
Debug.Print "OK=" & cnvHexStrFromBytes(ok)

' PART 2 - prefix the IV in the output
ctlen = CIPHER_EncryptBytes(0, 0, pt(0), ptlen, key(0), keylen, iv(0), ivlen, algstr, PKI_IV_PREFIX)
Debug.Print "CIPHER_EncryptBytes(PKI_IV_PREFIX) returns " & ctlen
ReDim ct(ctlen - 1)
ctlen = CIPHER_EncryptBytes(ct(0), ctlen, pt(0), ptlen, key(0), keylen, iv(0), ivlen, algstr, PKI_IV_PREFIX)

Debug.Print "IV||CT=" & cnvHexStrFromBytes(ct)

```

This should result in output as follows:

```

Aes128/CBC/OneAndZeroes
KY=0123456789ABCDEFF0E1D2C3B4A59687
IV=FEDCBA9876543210FEDCBA9876543210
PT=4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F
PT='Now is the time for all good men to'
CIPHER_EncryptBytes returns 48
CT=C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B
OK=C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B

```

*[New in v12.3]*
Use the `PKI_IV_PREFIX` option to prepend the IV to the ciphertext in the output.

```

CIPHER_EncryptBytes(PKI_IV_PREFIX) returns 64
IV||CT=FEDCBA9876543210FEDCBA9876543210C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B
       <------IV (16 bytes)-----------><--------CT (48 bytes)------------------------------------------------------------------------->

```

For another example of using `PKI_IV_PREFIX` see the second example in 
[CIPHER_DecryptBytes](#CIPHER_DecryptBytes).

### Example (VBA wrapper function)

```

Dim key() As Byte
Dim iv() As Byte
Dim pt() As Byte
Dim ct() As Byte
Dim dt() As Byte
Dim algstr As String

' PART 1
algstr = "Aes128/CBC/OneAndZeroes"
Debug.Print algstr
key = cnvBytesFromHexStr("0123456789ABCDEFF0E1D2C3B4A59687")
iv = cnvBytesFromHexStr("FEDCBA9876543210FEDCBA9876543210")
' "Now is the time for all good men to"
pt = cnvBytesFromHexStr("4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F")

ct = cipherEncryptBytes(pt, key, iv, algstr, 0)
Debug.Print "CT=" & cnvHexStrFromBytes(ct)
Debug.Print "OK=C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B"

dt = cipherDecryptBytes(ct, key, iv, algstr, 0)
Debug.Print "dt='" & StrConv(dt, vbUnicode) & "'"

' PART 2 - Use CTR mode and prefix the IV in the output
algstr = "Aes128/CTR"
Debug.Print algstr & " + PREFIX"
ct = cipherEncryptBytes(pt, key, iv, algstr, PKI_IV_PREFIX)
Debug.Print "CT=" & cnvHexStrFromBytes(ct)
dt = cipherDecryptBytes(ct, key, iv, algstr, PKI_IV_PREFIX)
Debug.Print "dt='" & StrConv(dt, vbUnicode) & "'"

' PART 3 - Use ECB mode and note we use a dummy empty byte array for the IV
Dim dummy() As Byte
algstr = "Aes128/ECB"
Debug.Print algstr
ct = cipherEncryptBytes(pt, key, dummy, algstr, 0)
Debug.Print "CT=" & cnvHexStrFromBytes(ct)
dt = cipherDecryptBytes(ct, key, dummy, algstr, 0)
Debug.Print "dt='" & StrConv(dt, vbUnicode) & "'"

```

### See Also

[CIPHER_DecryptBytes](#CIPHER_DecryptBytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CIPHER_EncryptBytes2"></a>CIPHER_EncryptBytes2
-----------------------------------------------------

@deprecated use `[CIPHER_EncryptBytes](#CIPHER_EncryptBytes)`.

<a id="CIPHER_EncryptHex"></a>CIPHER_EncryptHex
-----------------------------------------------

Encrypt data using the specified block cipher algorithm, mode and padding. 
The input data, key and initialization vector are all represented as hexadecimal strings.

### VBA/VB6 Syntax

`Public Declare Function CIPHER_EncryptHex Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strInputHex As String, ByVal strKeyHex As String, ByVal strIvHex As String, ByVal strAlgModePad As String, ByVal nOptions As Long) As Long`

`nRet = CIPHER_EncryptHex(strOutput, nOutChars, strInputHex, strKeyHex, strIvHex, strAlgModePad, nOptions)`

### C/C++ Syntax

`long __stdcall CIPHER_EncryptHex(char *szOutput, long nOutChars, const char *szInputHex, const char *szKeyHex, const char *szIvHex, const char *szAlgModePad, long nOptions);`

### Parameters

*szOutput*
:   [out] string buffer of sufficient length to receive the output.

*nOutChars*
:   [in] maximum number of characters to be received.

*szInputHex*
:   [in] the input data in hex format.

*szKeyHex*
:   [in] the key in hex format.

*szIvHex*
:   [in] the initialization vector (IV) in hex format, ignored for ECB mode (use `""`).

*szAlgModePad*
:   [in] string specifying the block cipher algorithm, mode and padding
(see [Specifying the algorithm, mode and padding for generic block cipher functions](#cipheralgmode)).

*nOptions*
:   [in] option flags:  

	Zero (0) for default options. Optionally add:  

`PKI_IV_PREFIX` to prepend the IV before the ciphertext in the output (ignored for ECB mode).

### Returns (VBA/C)

If successful, the return value is the number of characters in or required in the output;
otherwise it returns a nonzero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cipherEncryptHex`](#VB_cipherEncryptHex) (szInputHex As String, szKeyHex As String, szIvHex As String, szAlgModePad As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Cipher.Encrypt Method](#M_Cipher_Encrypt_StringStringStringCipherAlgorithmModePaddingCipher_Opts) (String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts)  

### Python Equivalent

static [Cipher.encrypt_hex](https://cryptosys.net/pki/pydocpki/class-stubs/Cipher.html#cryptosyspki.Cipher.encrypt_hex "External link")(datahex, keyhex, ivhex='', algmodepad='', alg=None, mode=Mode.ECB, pad=Pad.DEFAULT, opts=Opts.DEFAULT)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

This is the equivalent of [`CIPHER_EncryptBytes`](#CIPHER_EncryptBytes) with all parameters passed as hex-encoded strings instead of byte arrays.
It is similar to the [`CIPHER_Hex`](#CIPHER_Hex) function except this accepts variable-length input and adds padding if required, as well as the option to prepend the IV to the ciphertext.

Padding is added as specified to the input before encryption. The output will always be at least as long as the input,
or longer if padding or a prefixed IV is to be added.

The algorithm/mode/padding must be specified using either the *szAlgModePad* string or *nOptions* parameter,
but not both
(see [Specifying the algorithm, mode and padding for generic block cipher functions](#cipheralgmode)).

It is an error (`BAD_PARAM_ERROR`) to pass the empty string `""` as input in *szInputHex*.
The output buffer *strOutput* should *not* be the same as the input *strInputHex*.

Use the `PKI_IV_PREFIX` option to prepend the IV before the ciphertext in the output.
This will add the IV before the ciphertext in the form `IV||CT`.
This is the scheme used with block ciphers in XML encryption (see section 5.2 of [[XMLENC](#XMLENC)])
where they use the phrase "The resulting cipher text is prefixed by the IV."

### Example (VBA core function)

```

Dim strKey As String
Dim strIV As String
Dim strPlain As String
Dim strCipher As String
Dim strOK As String
Dim strAlg As String
Dim nChars As Long

strAlg = "Aes128/CBC/OneAndZeroes"
Debug.Print strAlg
strKey = "0123456789ABCDEFF0E1D2C3B4A59687"
strIV = "FEDCBA9876543210FEDCBA9876543210"
Debug.Print "KY=" & strKey
Debug.Print "IV=" & strIV
' "Now is the time for all good men to"
strPlain = "4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F"
Debug.Print "PT=" & strPlain
Debug.Print "PT='" & cnvStringFromHexStr(strPlain) & "'"
' Correct result
strOK = "C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B"

' 1. Find out how long an output buffer we need
nChars = CIPHER_EncryptHex(vbNullString, 0, strPlain, strKey, strIV, strAlg, 0)
Debug.Print "CIPHER_EncryptHex returns " & nChars
Debug.Assert nChars > 0
' 2. Allocate the buffer
strCipher = String(nChars, " ")
' 3. Encrypt to output buffer
nChars = CIPHER_EncryptHex(strCipher, nChars, strPlain, strKey, strIV, strAlg, 0)

Debug.Print "CT=" & strCipher
Debug.Print "OK=" & strOK

' PART 2 - prefix the IV in the output
nChars = CIPHER_EncryptHex(vbNullString, 0, strPlain, strKey, strIV, strAlg, PKI_IV_PREFIX)
Debug.Print "CIPHER_EncryptHex(PKI_IV_PREFIX) returns " & nChars
Debug.Assert nChars > 0
strCipher = String(nChars, " ")
nChars = CIPHER_EncryptHex(strCipher, nChars, strPlain, strKey, strIV, strAlg, PKI_IV_PREFIX)

Debug.Print "IV||CT=" & strCipher

```

This should result in output as follows:

```

Aes128/CBC/OneAndZeroes
KY=0123456789ABCDEFF0E1D2C3B4A59687
IV=FEDCBA9876543210FEDCBA9876543210
PT=4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F
PT='Now is the time for all good men to'
CIPHER_EncryptHex returns 96
CT=C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B
OK=C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B
CIPHER_EncryptHex(PKI_IV_PREFIX) returns 128
IV||CT=FEDCBA9876543210FEDCBA9876543210C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B

```

### Example (VBA wrapper function)

```

Dim strKeyHex As String
Dim strIvHex As String
Dim strPlainHex As String
Dim strCipherHex As String
strKeyHex = "0123456789ABCDEFF0E1D2C3B4A59687"
strIvHex = "FEDCBA9876543210FEDCBA9876543210"
strPlainHex = "4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F"

' Get encrypted output directly in hex
strCipherHex = cipherEncryptHex(strPlainHex, strKeyHex, strIvHex, "Aes128/CBC/OneAndZeroes", 0)
Debug.Print strCipherHex

' Same again with bytes
Dim lpKey() As Byte
Dim lpIV() As Byte
Dim lpPlain() As Byte
Dim lpCipher() As Byte
lpPlain = StrConv("Now is the time for all good men to", vbFromUnicode)
lpKey = cnvBytesFromHexStr("0123456789ABCDEFF0E1D2C3B4A59687")
lpIV = cnvBytesFromHexStr("FEDCBA9876543210FEDCBA9876543210")
' Get encrypted output
lpCipher = cipherEncryptBytes(lpPlain, lpKey, lpIV, "Aes128/CBC/OneAndZeroes", 0)
Debug.Print cnvHexStrFromBytes(lpCipher)

' Same again using ECB mode with default PKCS#5 padding
' To pass an empty byte array for IV, create a dummy zero-length array
Dim lpDummy() As Byte
lpCipher = cipherEncryptBytes(lpPlain, lpKey, lpDummy, "Aes128/ECB", 0)
Debug.Print cnvHexStrFromBytes(lpCipher)

' The old way - we need all the byte array lengths
Dim nBytes As Long
Dim nDataLen As Long
Dim nKeyLen As Long
Dim nIVLen As Long
nDataLen = cnvBytesLen(lpPlain)
nKeyLen = cnvBytesLen(lpKey)
nIVLen = cnvBytesLen(lpIV)
nBytes = CIPHER_EncryptBytes(ByVal 0&, 0, lpPlain(0), nDataLen, lpKey(0), nKeyLen, lpIV(0), nIVLen, "Aes128/CBC/OneAndZeroes", 0)
Debug.Assert nBytes > 0
ReDim lpCipher(nBytes - 1)
nBytes = CIPHER_EncryptBytes(lpCipher(0), nBytes, lpPlain(0), nDataLen, lpKey(0), nKeyLen, lpIV(0), nIVLen, "Aes128/CBC/OneAndZeroes", 0)
Debug.Print cnvHexStrFromBytes(lpCipher)

' Same again with hex using ECB mode with default PKCS#5 padding
' To pass a "null" IV in hex, just use the empty string
strCipherHex = cipherEncryptHex(strPlainHex, strKeyHex, "", "Aes128/ECB", 0)
Debug.Print strCipherHex

' Or vbNullString
strCipherHex = cipherEncryptHex(strPlainHex, strKeyHex, vbNullString, "Aes128/ECB", 0)
Debug.Print strCipherHex

```

### See Also

[CIPHER_DecryptHex](#CIPHER_DecryptHex)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CIPHER_File"></a>CIPHER_File
-----------------------------------

Encrypt or decrypt data in a file using the specified block cipher algorithm and mode. 
  

@deprecated 
Use [CIPHER_FileEncrypt()](#CIPHER_FileEncrypt) or [CIPHER_FileDecrypt()](#CIPHER_FileDecrypt) instead.

### VBA/VB6 Syntax

`Public Declare Function CIPHER_File Lib "diCrPKI.dll" 
(ByVal fEncrypt As Long, ByVal strFileOut As String, ByVal strFileIn As String, 
ByRef lpKey As Byte, ByRef lpIV As Byte, ByVal strAlgAndMode As String, ByVal nOptions As Long) As Long`

`nRet = CIPHER_File(fEncrypt, strFileOut, strFileIn, lpKey(0), 
lpIV(0), strAlgAndMode, nOptions)`

### C/C++ Syntax

`long __stdcall CIPHER_File(long fEncrypt, const char *szFileOut, const char *szFileIn, const unsigned char *lpKey, const unsigned char *lpIV, const char *szAlgAndMode, long nOptions);`

### Parameters

*fEncrypt*
:   [in] direction flag: 
set as `ENCRYPT` (True) to encrypt or `DECRYPT` (False) to decrypt.

*szFileOut*
:   [in] with the full path name of the output file to be created.

*szFileIn*
:   [in] with the full path name of the input file to be processed.

*lpKey*
:   [in] array containing the key.

*lpIV*
:   [in] containing the
initialization vector (IV), or zero (0) for ECB mode.

*szAlgAndMode*
:   [in] containing the block cipher algorithm and mode
(see [Specifying the algorithm and mode for generic block cipher functions](#cipheralgmode)).

*nOptions*
:   [in] option flags.

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

[Cipher.FileEncrypt Method](#M_Cipher_FileEncrypt_StringStringByteByteCipherAlgorithmModePaddingCipher_Opts)  

[Cipher.FileDecrypt Method](#M_Cipher_FileDecrypt_StringStringByteByteCipherAlgorithmModePaddingCipher_Opts)  

### Remarks

The key and initialization vector are passed as bytes arrays. PKCS5 padding is used, if required.
The algorithm and mode must be specified using either the *szAlgAndMode* or *nOptions* parameter 
(see [Specifying the algorithm and mode for generic block cipher functions](#cipheralgmode)).

The length of key *lpKey* must be *exactly* the required key size, 
and the length of the IV, if required, *exactly* the block size.
See [Valid key and block sizes](#blockciphersizes).

The output file *szFileOut* will be overwritten without warning.
If there is an error, the output file will **not exist**.
The input and output files must **not** be the same.

In ECB and CBC modes, a padding string will be added or assumed according to the method outlined in Section 6.3 of
[[CMS](#CMS)], 
which is the same as the padding method in [[PKCS7](#PKCS7)] section 10.3 and [[PKCS5](#PKCS5)] section 6.1.1
and [[RFC1423](#RFC1423)] para 1.1.

### Example

```

Const MY_PATH As String = ""
Dim abKey() As Byte
Dim abIV() As Byte
Dim strFileEnc As String
Dim strFileIn As String
Dim strFileChk As String
Dim nRet As Long

' Construct full path names to files
strFileIn = MY_PATH & "hello.txt"
strFileEnc = MY_PATH & "hello.aes128.enc.dat"
strFileChk = MY_PATH & "hello.aes128.chk.txt"

' Create the key as an array of bytes
' This creates an array of 16 bytes {&HFE, &HDC, ... &H10}
abKey = cnvBytesFromHexStr("fedcba9876543210fedcba9876543210")
' Create the IV at random
ReDim abIV(PKI_BLK_AES_BYTES - 1)
Call RNG_Bytes(abIV(0), PKI_BLK_AES_BYTES, "", 0)
' Display the IV (this needs to be communicated separately to the recipient)
Debug.Print "IV=" & cnvHexStrFromBytes(abIV)

' Encrypt plaintext file to ciphertext using AES-128 in counter (CTR) mode
' (This will create a file of exactly the same size as the input)
nRet = CIPHER_File(ENCRYPT, strFileEnc, strFileIn, abKey(0), abIV(0), "aes128-ctr", 0)
Debug.Print "CIPHER_File(ENCRYPT) returns " & nRet

' Now decrypt it
nRet = CIPHER_File(DECRYPT, strFileChk, strFileEnc, abKey(0), abIV(0), "aes128-ctr", 0)
Debug.Print "CIPHER_File(DECRYPT) returns " & nRet

```

### See Also

[CIPHER_Bytes](#CIPHER_Bytes)
[CIPHER_Hex](#CIPHER_Hex)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CIPHER_FileDecrypt"></a>CIPHER_FileDecrypt
-------------------------------------------------

Decrypt a file using specified block cipher algorithm, mode and padding.

### VBA/VB6 Syntax

`Public Declare Function CIPHER_FileDecrypt Lib "diCrPKI.dll" 
(ByVal strFileOut As String, ByVal strFileIn As String, 
ByRef lpKey As Byte, ByVal nKeyLen As Long, ByRef lpIV As Byte, ByVal nKeyLen As Long, 
ByVal strAlgModePad As String, ByVal nOptions As Long) As Long`

`nRet = CIPHER_FileDecrypt(strFileOut, strFileIn, lpKey(0), nKeyLen, lpIV(0), nIvLen, strAlgModePad, nOptions)`

### C/C++ Syntax

`long __stdcall CIPHER_FileDecrypt(const char *szFileOut, const char *szFileIn, const unsigned char *lpKey, long nKeyLen, const unsigned char *lpIV, long nIvLen, const char *szAlgModePad, long nOptions);`

### Parameters

*szFileOut*
:   [in] with the full path name of the output file to be created.

*szFileIn*
:   [in] with the full path name of the input file to be processed.

*lpKey*
:   [in] array containing the key.

*nKeyLen*
:   [in] specifying the length of the key in bytes.

*lpIV*
:   [in] containing the initialization vector (IV), if required.

*nIvLen*
:   [in] specifying the length of the IV in bytes.

*szAlgModePad*
:   [in] containing the block cipher algorithm, mode and padding
(see [Specifying the algorithm, mode and padding for generic block cipher functions](#cipheralgmode)).

*nOptions*
:   [in] option flags:  

	Zero (0) for default options. Optionally add:  

`PKI_IV_PREFIX` to expect the IV to be prepended at the start of the file (ignored for ECB mode).

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cipherFileDecrypt`](#VB_cipherFileDecrypt) (szFileOut As String, szFileIn As String, lpKey() As Byte, lpIV() As Byte, szAlgModePad As String, Optional nOptions As Long = 0) As Long

### .NET Equivalent

[Cipher.FileDecrypt Method](#M_Cipher_FileDecrypt_StringStringByteByteCipherAlgorithmModePaddingCipher_Opts) (String, String, Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)  

[Cipher.FileDecrypt Method](#M_Cipher_FileDecrypt_StringStringStringStringCipherAlgorithmModePaddingCipher_Opts) (String, String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts)  

### C++ (STL) Equivalent

static int [dipki::Cipher::FileDecrypt](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#ac4575aa726b28151e63bc39523aba95a "External link") (const std::string &fileOut, const std::string &fileIn, const bvec_t &key, const bvec_t &iv, Alg alg, Mode mode=Mode::ECB, Padding pad=Padding::Default, Opts opts=Opts::None)

### Python Equivalent

static [Cipher.file_decrypt](https://cryptosys.net/pki/pydocpki/class-stubs/Cipher.html#cryptosyspki.Cipher.file_decrypt "External link")(fileout, filein, key, iv, algmodepad='', alg=None, mode=Mode.ECB, pad=Pad.DEFAULT, opts=Opts.DEFAULT)

### Remarks

The algorithm/mode/padding must be specified using either the *szAlgModePad* string or *nOptions* parameter,
but not both
(see [Specifying the algorithm, mode and padding for generic block cipher functions](#cipheralgmode)).

The length of key must be *exactly* the required key size, 
and the length of the IV, if required, *exactly* the block size.
See [Valid key and block sizes](#blockciphersizes).

The output file *szFileOut* will be overwritten without warning.
If there is an error, the output file will **not exist**.
The input and output files must **not** be the same.

**Prepended IV:** If the ciphertext file was created with the IV prepended at the start of the file, then you 
	*must* specify the `PKI_IV_PREFIX` option. In this case, the *lpIV* parameter is ignored and should be set to NULL.
	The input file is expected to be of the form `IV||ciphertext`, or
	`IV||ciphertext||tag`	for AES-GCM.

**Defaults:** If padding is not specified then the default padding method depends on the cipher mode: 
`pkcs5padding` will be used for ECB and CBC mode and `nopadding` for all other modes.
The default cipher mode is `ECB`. 
Thus `"aes128"` is the same as `"aes128/ecb/pkcs5padding"`.

**Padding:** When decrypting you can specify `NoPadding` to leave any padding intact in the deciphered file.
	This is useful if you wish to examine an unknown padding scheme.
Otherwise, when decrypting in ECB or CBC mode, you *must* specify the same padding scheme used when encrypting.
It is an error (`DECRYPT_ERROR`) if the expected padding string is not found after decrypting.
The padding parameter is ignored when decrypting in CTR, OFB or CFB mode.

**GCM mode:** *[New in v20.7]* Use `aes*-gcm` to decrypt the file using AES-GCM mode.
A 16-byte tag (mac) *must* be appended at the end of the file. Only a 16-byte tag is supported.
The IV *must* be exactly 12 bytes long for AES-GCM mode.
Use the `PKI_IV_PREFIX` flag to indicate that the IV is at the start of the file.

### Example

See example in [CIPHER_FileEncrypt](#CIPHER_FileEncrypt).

### See Also

[CIPHER_FileEncrypt](#CIPHER_FileEncrypt)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CIPHER_FileEncrypt"></a>CIPHER_FileEncrypt
-------------------------------------------------

Encrypt a file using specified block cipher algorithm, mode and padding. 
The IV may be prepended to the file, if required.

### VBA/VB6 Syntax

`Public Declare Function CIPHER_FileEncrypt Lib "diCrPKI.dll" 
(ByVal strFileOut As String, ByVal strFileIn As String, 
ByRef lpKey As Byte, ByVal nKeyLen As Long, ByRef lpIV As Byte, ByVal nKeyLen As Long, 
ByVal strAlgModePad As String, ByVal nOptions As Long) As Long`

`nRet = CIPHER_FileEncrypt(strFileOut, strFileIn, lpKey(0), nKeyLen,
lpIV(0), nIvLen, strAlgModePad, nOptions)`

### C/C++ Syntax

`long __stdcall CIPHER_FileEncrypt(const char *szFileOut, const char *szFileIn, const unsigned char *lpKey, long nKeyLen, const unsigned char *lpIV, long nIvLen, const char *szAlgModePad, long nOptions);`

### Parameters

*szFileOut*
:   [in] with the full path name of the output file to be created.

*szFileIn*
:   [in] with the full path name of the input file to be processed.

*lpKey*
:   [in] array containing the key.

*nKeyLen*
:   [in] specifying the length of the key in bytes.

*lpIV*
:   [in] containing the initialization vector (IV), if required.

*nIvLen*
:   [in] specifying the length of the IV in bytes.

*szAlgModePad*
:   [in] containing the block cipher algorithm, mode and padding
(see [Specifying the algorithm, mode and padding for generic block cipher functions](#cipheralgmode)).

*nOptions*
:   [in] option flags:  

	Zero (0) for default options. Optionally add:  

`PKI_IV_PREFIX` to prepend the IV before the ciphertext in the output file (ignored for ECB mode).

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cipherFileEncrypt`](#VB_cipherFileEncrypt) (szFileOut As String, szFileIn As String, lpKey() As Byte, lpIV() As Byte, szAlgModePad As String, Optional nOptions As Long = 0) As Long

### .NET Equivalent

[Cipher.FileEncrypt Method](#M_Cipher_FileEncrypt_StringStringByteByteCipherAlgorithmModePaddingCipher_Opts) (String, String, Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)  

[Cipher.FileEncrypt Method](#M_Cipher_FileEncrypt_StringStringStringStringCipherAlgorithmModePaddingCipher_Opts) (String, String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts)  

### C++ (STL) Equivalent

static int [dipki::Cipher::FileEncrypt](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#ae15ee22f917aca4fae21ee1c8ab2a8fd "External link") (const std::string &fileOut, const std::string &fileIn, const bvec_t &key, const bvec_t &iv, Alg alg, Mode mode=Mode::ECB, Padding pad=Padding::Default, Opts opts=Opts::None)

### Python Equivalent

static [Cipher.file_encrypt](https://cryptosys.net/pki/pydocpki/class-stubs/Cipher.html#cryptosyspki.Cipher.file_encrypt "External link")(fileout, filein, key, iv, algmodepad='', alg=None, mode=Mode.ECB, pad=Pad.DEFAULT, opts=Opts.DEFAULT)

### Remarks

The algorithm/mode/padding must be specified using either the *szAlgModePad* string or *nOptions* parameter,
but not both
(see [Specifying the algorithm, mode and padding for generic block cipher functions](#cipheralgmode)).

The length of key must be *exactly* the required key size, 
and the length of the IV, if required, *exactly* the block size.
See [Valid key and block sizes](#blockciphersizes).

The output file *szFileOut* will be overwritten without warning.
If there is an error, the output file will **not exist**.
The input and output files must **not** be the same.

**Prepended IV:** If the `PKI_IV_PREFIX` option flag is set in *nOptions* then the IV will be
prepended (i.e. added) at the start of the output file.
That is, the output file will be of the form `IV||ciphertext`.
The `PKI_IV_PREFIX` flag is ignored in ECB mode where an IV is not needed.

**Defaults:** If padding is not specified then the default padding method depends on the cipher mode: 
`pkcs5padding` will be used for ECB and CBC mode and `nopadding` for all other modes.
The default cipher mode is `ECB`. 
Thus `"aes128"` is the same as `"aes128/ecb/pkcs5padding"`.

**Padding:** In normal circumstances you should leave the padding unspecified and use the default padding when encrypting.
The only time it should be required is if you want to use an exotic padding like `OneAndZeroesPadding` 
instead of `pkcs5padding` with EBC or CBC mode.
Note that, unlike the behaviour with `[CIPHER_EncryptBytes](#CIPHER_EncryptBytes)`,
it is an error (`BAD_PARAM_ERROR`) to specify `NoPadding` when encrypting a file with ECB or CBC mode 
*under any circumstances*.
The padding option is ignored for CTR, OFB and CFB modes; that is,
the default `nopadding` is *always* used for these modes regardless of what is specified (so just use the default, 
e.g. `"aes128/ctr"`).

**GCM mode:** *[New in v21.0]* Use `aes128-gcm`, `aes192-gcm` or `aes256-gcm` 
to encrypt the file using AES-GCM mode.
A 16-byte tag (mac) is *always* appended to the file. 
The IV *must* be exactly 12 bytes long for AES-GCM mode.
Add the `PKI_IV_PREFIX` flag to prepend the IV at the start of the output file
(this is in accordance with section 5.2.4 of [[XMLENC](#XMLENC)]).

### Example

```

Dim abKey() As Byte
Dim abIV() As Byte
Dim nKeyLen As Long
Dim nIvLen As Long
Dim strFileEnc As String
Dim strFileIn As String
Dim strFileChk As String
Dim strAlgModePad As String
Dim nRet As Long

' Construct full path names to files
strFileIn = "hello.txt"
strFileEnc = "hello.aes192.enc.dat"
strFileChk = "hello.aes192.chk.txt"

' Check input file
Debug.Print "FileLen('" & strFileIn & "')=" & FileLen(strFileIn)

' Create the AES-192 key as an array of 24 bytes
abKey = cnvBytesFromHexStr("fedcba9876543210fedcba98765432101122334455667788")
nKeyLen = UBound(abKey) + 1
Debug.Print "KY=" & cnvHexStrFromBytes(abKey)
Debug.Print "LEN(KY)=" & nKeyLen
' Create the IV at random
ReDim abIV(PKI_BLK_AES_BYTES - 1)
Call RNG_Bytes(abIV(0), PKI_BLK_AES_BYTES, "", 0)
' Display the IV (this will be prepended to the ciphertext in the output file)
Debug.Print "IV=" & cnvHexStrFromBytes(abIV)
nIvLen = UBound(abIV) + 1
Debug.Print "LEN(IV)=" & nIvLen

' Specify cipher alg/mode/padding
strAlgModePad = "aes192/CBC/ANSIX923"
Debug.Print strAlgModePad

' Encrypt the plaintext file, prefixing the IV
nRet = CIPHER_FileEncrypt(strFileEnc, strFileIn, abKey(0), nKeyLen, abIV(0), nIvLen, strAlgModePad, PKI_IV_PREFIX)
Debug.Print "CIPHER_FileEncrypt() returns " & nRet & " (expected 0)"
Debug.Assert (0 = nRet)

' Check output file
Debug.Print "FileLen('" & strFileEnc & "')=" & FileLen(strFileEnc)

' Now decipher using the IV already prefixed to the ciphertext
nRet = CIPHER_FileDecrypt(strFileChk, strFileEnc, abKey(0), nKeyLen, 0, 0, strAlgModePad, PKI_IV_PREFIX)
Debug.Print "CIPHER_FileDecrypt() returns " & nRet & " (expected 0)"
Debug.Assert (0 = nRet)

' Check decrypted file - it should match the original plaintext
Debug.Print "FileLen('" & strFileChk & "')=" & FileLen(strFileChk)
Debug.Assert (FileLen(strFileChk) = FileLen(strFileIn))

```

The input file is 13 bytes long (`"hello world\r\n"`). This is padded to 16 bytes when encrypted in CBC mode.
The output file contains 16 bytes of ciphertext plus the prepended IV of 16 bytes,
so it is 32 bytes long.

```

FileLen('hello.txt')=13
KY=FEDCBA9876543210FEDCBA98765432101122334455667788
LEN(KY)=24
IV=ECD982FF61DDC6506828690D20B55BBE
LEN(IV)=16
aes192/CBC/ANSIX923
CIPHER_FileEncrypt() returns 0 (expected 0)
FileLen('hello.aes192.enc.dat')=32
CIPHER_FileDecrypt() returns 0 (expected 0)
FileLen('hello.aes192.chk.txt')=13

```

### See Also

[CIPHER_FileDecrypt](#CIPHER_FileDecrypt)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CIPHER_Hex"></a>CIPHER_Hex
---------------------------------

Encrypt or decrypt data represented as a hexadecimal string.  
The key and initialization vector are represented as a hexadecimal string.

### VBA/VB6 Syntax

`Public Declare Function CIPHER_Hex Lib "diCrPKI.dll" 
(ByVal fEncrypt As Long, ByVal strOutput As String, ByVal nOutChars As Long, ByVal strData As String, 
ByVal strKey As String, ByVal strIV As String, ByVal strAlgAndMode As String, ByVal nOptions As Long) As Long`

`nRet = CIPHER_Hex(fEncrypt, strOutput, nOutChars, strInput, strKey, strIV, strAlgAndMode, nOptions)`

### C/C++ Syntax

`long __stdcall CIPHER_Hex(long fEncrypt, char *szOutput, long nOutChars, const char *szData, const char *szKey, const char *szIV, const char *szAlgAndMode, long nOptions);`

### Parameters

*fEncrypt*
:   [in] direction flag: 
set as `ENCRYPT` (True) to encrypt or `DECRYPT` (False) to decrypt.

*szOutput*
:   [out] of sufficient length to receive the output.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szData*
:   [in] containing the input data in hex format.

*szKey*
:   [in] containing the key in hex format.

*szIV*
:   [in] containing the initialization vector (IV)
in hex format, or the empty string `""` for ECB mode.

*szAlgAndMode*
:   [in] containing the block cipher algorithm and mode
(see [Specifying the algorithm and mode for generic block cipher functions](#cipheralgmode)).

*nOptions*
:   [in] option flags.

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

[Cipher.Encrypt Method](#M_Cipher_Encrypt_StringStringStringCipherAlgorithmMode) (String, String, String, CipherAlgorithm, Mode)  

[Cipher.Decrypt Method](#M_Cipher_Decrypt_StringStringStringCipherAlgorithmMode) (String, String, String, CipherAlgorithm, Mode)  

### Remarks

The algorithm and mode must be specified using either the *szAlgAndMode* or *nOptions* parameter 
(see [Specifying the algorithm and mode for generic block cipher functions](#cipheralgmode)).
All data parameters are expected to be in hexadecimal-encoded format and to be of valid lengths. 
Valid hexadecimal characters are [0-9A-Fa-f].
The hex-encoded key string *szKey* must represent a value with a length of 
*exactly* the required key size.
The hex-encoded initialization vector string *szIV*, if required, must represent a value with a length of 
*exactly* the block size.
See [Valid key and block sizes](#blockciphersizes).

**Important:** The output string *szOutput* must be dimensioned with at least the same
number of characters as the input string before calling.
The variables *szOutput* and *szInput* should be different.

For ECB and CBC modes, the length of the input string *szInput* must be an exact multiple of 
the block size encoded in hex characters 
otherwise a `BAD_LENGTH_ERROR` error will occur. 
It is the responsibility of the user to provide suitable padding before encrypting in those modes
and to remove any padding after decrypting.

*[New in v20.0]*
Consider using the newer functions [CIPHER_EncryptHex](#CIPHER_EncryptHex) and [CIPHER_DecryptHex](#CIPHER_DecryptHex). 
These functions take a variable length input and add (or remove) the required padding, and provide the option to prepend the IV to the ciphertext.

### Example

This example is from Section 8.1 of [SMIME-EX].

```

Dim nRet As Long
Dim sPlain As String
Dim sCipher As String
Dim sCheck As String
Dim sKey As String
Dim sInitV As String
Dim sCorrect As String

sPlain = "5468697320736F6D652073616D706520636F6E74656E742E0808080808080808"
'         T h i s _ s o m e _ s a m p e _ c o n t e n t .(+padding 8 x 08)
sKey = "737C791F25EAD0E04629254352F7DC6291E5CB26917ADA32"
sInitV = "B36B6BFB6231084E"
sCorrect = "d76fd1178fbd02f84231f5c1d2a2f74a4159482964f675248254223daf9af8e4"
' Set output to be same length as input
sCipher = String(Len(sPlain), " ")

Debug.Print "KY=" & sKey
Debug.Print "PT=" & sPlain
' Encrypt using strAlgAndMode
nRet = CIPHER_Hex(ENCRYPT, sCipher, Len(sCipher), sPlain, sKey, sInitV, "tdea-cbc", 0)
Debug.Print "CT=" & sCipher & nRet
Debug.Print "OK=" & sCorrect
' Alternative using nOptions
nRet = CIPHER_Hex(ENCRYPT, sCipher, Len(sCipher), sPlain, sKey, sInitV, "", PKI_BC_TDEA + PKI_MODE_CBC)
Debug.Print "CT=" & sCipher & nRet
Debug.Print "OK=" & sCorrect

' Decrypt using strAlgAndMode
sCheck = String(Len(sCipher), " ")
nRet = CIPHER_Hex(DECRYPT, sCheck, Len(sCheck), sCipher, sKey, sInitV, "tdea-cbc", 0)
Debug.Print "P'=" & sCheck & nRet
' Alternative using nOptions
sCheck = String(Len(sCipher), " ")
nRet = CIPHER_Hex(DECRYPT, sCheck, Len(sCheck), sCipher, sKey, sInitV, "", PKI_BC_TDEA + PKI_MODE_CBC)
Debug.Print "P'=" & sCheck & nRet

```

This should result in output as follows:

```

KY=737C791F25EAD0E04629254352F7DC6291E5CB26917ADA32
PT=5468697320736F6D652073616D706520636F6E74656E742E0808080808080808
CT=D76FD1178FBD02F84231F5C1D2A2F74A4159482964F675248254223DAF9AF8E4 0 
OK=d76fd1178fbd02f84231f5c1d2a2f74a4159482964f675248254223daf9af8e4
CT=D76FD1178FBD02F84231F5C1D2A2F74A4159482964F675248254223DAF9AF8E4 0 
OK=d76fd1178fbd02f84231f5c1d2a2f74a4159482964f675248254223daf9af8e4
P'=5468697320736F6D652073616D706520636F6E74656E742E0808080808080808 0 
P'=5468697320736F6D652073616D706520636F6E74656E742E0808080808080808 0 

```

### See Also

[CIPHER_Bytes](#CIPHER_Bytes)
[CIPHER_File](#CIPHER_File)
[CIPHER_EncryptHex](#CIPHER_EncryptHex)
[CIPHER_DecryptHex](#CIPHER_DecryptHex)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CIPHER_KeyWrap"></a>CIPHER_KeyWrap
-----------------------------------------

Wrap a content-encryption key with a key-encryption key.

### VBA/VB6 Syntax

`Public Declare Function CIPHER_KeyWrap Lib "diCrPKI.dll" 
(ByRef lpOutput As Byte, ByVal nOutBytes As Long, 
ByRef lpData As Byte, ByVal nDataLen As Long, 
ByRef lpKek As Byte, ByVal nKekLen As Long, ByVal nOptions As Long) As Long`

`nRet = CIPHER_KeyWrap(lpOutput(0), nOutBytes, lpData(0), nDataLen, 
lpKek(0), nKekLen, nOptions)`

### C/C++ Syntax

`long __stdcall CIPHER_KeyWrap(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpData, long nDataLen, const unsigned char *lpKek, long nKekLen, long nOptions);`

### Parameters

*lpOutput*
:   [out] array of sufficient length to receive the output.

*nOutBytes*
:   [in] specifying the maximum length of the output array.

*lpData*
:   [in] array containing the input data (key material).

*nDataLen*
:   [in] specifying the length of the input data in bytes.

*lpKek*
:   [in] array containing the key encryption key.

*nKekLen*
:   [in] specifying the length of the key encryption key.

*nOptions*
:   [in] option flags:  

Select the key wrap algorithm from one of the following:  

`PKI_KWRAP_AES128` (or `PKI_BC_AES128`) to use `AES128-Wrap`  

`PKI_KWRAP_AES192` (or `PKI_BC_AES192`) to use `AES128-Wrap`  

`PKI_KWRAP_AES256` (or `PKI_BC_AES256`) to use `AES128-Wrap`  

`PKI_KWRAP_3DES` (or `PKI_BC_3DES`) to use `cms3DESWrap`

### Returns (VBA/C)

If successful, the return value is the number of bytes in the output;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cipherKeyWrap`](#VB_cipherKeyWrap) (lpData() As Byte, lpKEK() As Byte, nOptions As Long) As Byte()

### .NET Equivalent

[Cipher.KeyWrap Method](#M_Cipher_KeyWrap)  

### C++ (STL) Equivalent

static bvec_t [dipki::Cipher::KeyWrap](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#a9aebd1dab4c63244371c589d5ef5c9ba "External link") (const bvec_t &data, const bvec_t &kek, Alg alg)

### Python Equivalent

static [Cipher.key_wrap](https://cryptosys.net/pki/pydocpki/class-stubs/Cipher.html#cryptosyspki.Cipher.key_wrap "External link")(data, kek, alg)

### Remarks

This wraps (encrypts) key material using a key encryption key (KEK) and uses either the AES Key Wrap Algorithm
from [[RFC3394](#RFC3394)] or the 
Triple-DES Key Wrap algorithm from [[RFC3217](#RFC3217)].
There is no default algorithm. The algorithm must be specified in the *nOptions* parameter.
The input data to be wrapped must be a valid length for the underlying data encapsulation mechanism; 
specifically, at least 16 bytes and a multiple of 8 bytes for AES, or exactly 24 bytes for Triple DES.
To find the required length for the output wrapped key, pass zero as the *nOutBytes* parameter
(*Hint:* an AES-wrapped key is exactly 8 bytes longer than the input; a triple-DES-wrapped key is 16 bytes longer).
No parity bit checks or changes are made for a Triple-DES key.

*Changed in [v20.5]:* Added the explicit key wrap options `PKI_KWRAP_*` which are different from the old `PKI_BC_*` options.
The old `PKI_BC_*` options are still accepted for backwards compatibility.

### Example (VBA core function)

```

Dim abWK() As Byte
Dim abKeyData() As Byte
Dim abKek() As Byte
Dim nWkLen As Long
Dim nKdLen As Long
Dim nKekLen As Long

abKeyData = cnvBytesFromHexStr("00112233 44556677 8899aabb ccddeeff")
abKek = cnvBytesFromHexStr("c17a44e8 e28d7d64 81d1ddd5 0a3b8914")
nKdLen = UBound(abKeyData) + 1
nKekLen = UBound(abKek) + 1

nWkLen = CIPHER_KeyWrap(0, 0, abKeyData(0), nKdLen, abKek(0), nKekLen, PKI_BC_AES128)
If nWkLen <= 0 Then
    Debug.Print " returns " & nWkLen & ": " & pkiErrorLookup(nWkLen)
    Exit Sub
End If
ReDim abWK(nWkLen - 1)
nWkLen = CIPHER_KeyWrap(abWK(0), nWkLen, abKeyData(0), nKdLen, abKek(0), nKekLen, PKI_BC_AES128)
Debug.Print "WK=" & cnvHexStrFromBytes(abWK)

abKeyData = cnvBytesFromHexStr("8cbedec4 8d063e1b a46be8e3 69a9c398 d8e30ee5 42bc347c 4f30e928 ddd7db49")
abKek = cnvBytesFromHexStr("9e84ee99 e6a84b50 c76cd414 a2d2ec05 8af41bfe 4bf3715b f894c8da 1cd445f6")
nKdLen = UBound(abKeyData) + 1
nKekLen = UBound(abKek) + 1

nWkLen = CIPHER_KeyWrap(0, 0, abKeyData(0), nKdLen, abKek(0), nKekLen, PKI_BC_AES256)
If nWkLen <= 0 Then
    Debug.Print " returns " & nWkLen & ": " & pkiErrorLookup(nWkLen)
    Exit Sub
End If
ReDim abWK(nWkLen - 1)
nWkLen = CIPHER_KeyWrap(abWK(0), nWkLen, abKeyData(0), nKdLen, abKek(0), nKekLen, PKI_BC_AES256)
Debug.Print "WK=" & cnvHexStrFromBytes(abWK)

abKeyData = cnvBytesFromHexStr("84e7f2d8 78f89fcc cd2d5eba fc56daf7 3300f27e f771cd68")
abKek = cnvBytesFromHexStr("8ad8274e 56f46773 8edd83d4 394e5e29 af7c4089 e4f8d9f4")
nKdLen = UBound(abKeyData) + 1
nKekLen = UBound(abKek) + 1

nWkLen = CIPHER_KeyWrap(0, 0, abKeyData(0), nKdLen, abKek(0), nKekLen, PKI_BC_3DES)
If nWkLen <= 0 Then
    Debug.Print " returns " & nWkLen & ": " & pkiErrorLookup(nWkLen)
    Exit Sub
End If
ReDim abWK(nWkLen - 1)
nWkLen = CIPHER_KeyWrap(abWK(0), nWkLen, abKeyData(0), nKdLen, abKek(0), nKekLen, PKI_BC_3DES)
Debug.Print "WK=" & cnvHexStrFromBytes(abWK)

```

This should result in output as follows:

```

WK=503D75C73630A7B02ECF51B9B29B907749310B77B0B2E054
WK=EAFB901F82B98D37F17497063DE3E5EC7246AB57200AE73EDDDDF24AA403DAFA0C5AE151D1746FA4
WK=E6517B14A383D48AD71D2D80C98894A10C59901D69ABDF77E27A11B50370FAA21AF5231552D2C1F0

```

The AES key wrap will always give the same result for the same input data, 
but the triple DES result will be different each time.

### Example (VBA wrapper function)

```

Dim lpWK() As Byte
Dim lpKeyData() As Byte
Dim lpKek() As Byte

lpKeyData = cnvBytesFromHexStr("00112233 44556677 8899aabb ccddeeff")
lpKek = cnvBytesFromHexStr("c17a44e8 e28d7d64 81d1ddd5 0a3b8914")
' NB Specific nonzero option required in nOptions
lpWK = cipherKeyWrap(lpKeyData, lpKek, PKI_BC_AES128)
Debug.Print "WK=" & cnvHexStrFromBytes(lpWK)
Debug.Print "OK=503D75C73630A7B02ECF51B9B29B907749310B77B0B2E054"

' Now unwrap the KEK
Dim lpKeyUnwrapped() As Byte
lpKeyUnwrapped = cipherKeyUnwrap(lpWK, lpKek, PKI_BC_AES128)
Debug.Print "KY=" & cnvHexStrFromBytes(lpKeyUnwrapped)
Debug.Print "OK=00112233445566778899AABBCCDDEEFF"
```

### See Also

[CIPHER_KeyUnwrap](#CIPHER_KeyUnwrap)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CIPHER_KeyUnwrap"></a>CIPHER_KeyUnwrap
---------------------------------------------

Unwrap (decrypt) a content-encryption key with a key-encryption key.

### VBA/VB6 Syntax

`Public Declare Function CIPHER_KeyUnwrap Lib "diCrPKI.dll" 
(ByRef lpOutput As Byte, ByVal nOutBytes As Long, 
ByRef lpData As Byte, ByVal nDataLen As Long, 
ByRef lpKek As Byte, ByVal nKekLen As Long, ByVal nOptions As Long) As Long`

`nRet = CIPHER_KeyUnwrap(lpOutput(0), nOutBytes, lpData(0), nDataLen, lpKek(0), nKekLen, nOptions)`

### C/C++ Syntax

`long __stdcall CIPHER_KeyUnwrap(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpData, long nDataLen, const unsigned char *lpKek, long nKekLen, long nOptions);`

### Parameters

*lpOutput*
:   [out] array of sufficient length to receive the output.

*nOutBytes*
:   [in] specifying the maximum length of the output array.

*lpData*
:   [in] array containing the input data (wrapped key).

*nDataLen*
:   [in] specifying the length of the input data in bytes.

*lpKek*
:   [in] array containing the key encryption key.

*nKekLen*
:   [in] specifying the length of the key encryption key.

*nOptions*
:   [in] option flags:  

Select the key wrap algorithm from one of the following:  

`PKI_KWRAP_AES128` (or `PKI_BC_AES128`) to use `AES128-Wrap`  

`PKI_KWRAP_AES192` (or `PKI_BC_AES192`) to use `AES128-Wrap`  

`PKI_KWRAP_AES256` (or `PKI_BC_AES256`) to use `AES128-Wrap`  

`PKI_KWRAP_3DES` (or `PKI_BC_3DES`) to use `cms3DESWrap`

### Returns (VBA/C)

If successful, the return value is the number of bytes in the output;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cipherKeyUnwrap`](#VB_cipherKeyUnwrap) (lpData() As Byte, lpKEK() As Byte, nOptions As Long) As Byte()

### .NET Equivalent

[Cipher.KeyUnwrap Method](#M_Cipher_KeyUnwrap)  

### C++ (STL) Equivalent

static bvec_t [dipki::Cipher::KeyUnwrap](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#af55e7ae91b01993b1a6c02cc86c51a68 "External link") (const bvec_t &data, const bvec_t &kek, Alg alg)

### Python Equivalent

static [Cipher.key_unwrap](https://cryptosys.net/pki/pydocpki/class-stubs/Cipher.html#cryptosyspki.Cipher.key_unwrap "External link")(data, kek, alg)

### Remarks

This unwraps (decrypts) key material using a key encryption key (KEK) and uses either the AES Key Wrap Algorithm
from [[RFC3394](#RFC3394)] or the 
Triple-DES Key Wrap algorithm from [[RFC3217](#RFC3217)].
There is no default algorithm. The algorithm must be specified in the *nOptions* parameter.
To find the required length for the output key material, pass zero as the *nOutBytes* parameter.
This will be 8 bytes less than the input length for AES and 16 bytes less for triple DES.
No parity bit checks or changes are made for a Triple-DES key.

### Example (VBA core function)

```

Dim abWK() As Byte
Dim abKeyData() As Byte
Dim abKek() As Byte
Dim nWkLen As Long
Dim nKdLen As Long
Dim nKekLen As Long

abWK = cnvBytesFromHexStr("503D75C73630A7B02ECF51B9B29B907749310B77B0B2E054")
abKek = cnvBytesFromHexStr("c17a44e8 e28d7d64 81d1ddd5 0a3b8914")
nWkLen = UBound(abWK) + 1
nKekLen = UBound(abKek) + 1

nKdLen = CIPHER_KeyUnwrap(0, 0, abWK(0), nWkLen, abKek(0), nKekLen, PKI_BC_AES128)
If nKdLen <= 0 Then
    Debug.Print " returns " & nKdLen & ": " & pkiErrorLookup(nKdLen)
    Exit Sub
End If
ReDim abKeyData(nKdLen - 1)
nWkLen = CIPHER_KeyUnwrap(abKeyData(0), nKdLen, abWK(0), nWkLen, abKek(0), nKekLen, PKI_BC_AES128)
Debug.Print "K=" & cnvHexStrFromBytes(abKeyData)

```

This should result in output as follows:

```

K=00112233445566778899AABBCCDDEEFF

```

### Example (VBA wrapper function)

```

Dim lpWK() As Byte
Dim lpKeyData() As Byte
Dim lpKek() As Byte

lpKeyData = cnvBytesFromHexStr("00112233 44556677 8899aabb ccddeeff")
lpKek = cnvBytesFromHexStr("c17a44e8 e28d7d64 81d1ddd5 0a3b8914")
' NB Specific nonzero option required in nOptions
lpWK = cipherKeyWrap(lpKeyData, lpKek, PKI_BC_AES128)
Debug.Print "WK=" & cnvHexStrFromBytes(lpWK)
Debug.Print "OK=503D75C73630A7B02ECF51B9B29B907749310B77B0B2E054"

' Now unwrap the KEK
Dim lpKeyUnwrapped() As Byte
lpKeyUnwrapped = cipherKeyUnwrap(lpWK, lpKek, PKI_BC_AES128)
Debug.Print "KY=" & cnvHexStrFromBytes(lpKeyUnwrapped)
Debug.Print "OK=00112233445566778899AABBCCDDEEFF"
```

### See Also

[CIPHER_KeyWrap](#CIPHER_KeyWrap)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CMS_GetSigDataDigest"></a>CMS_GetSigDataDigest
-----------------------------------------------------

Extracts the message digest from a signed-data CMS object file and verifies the 
signature.

### VBA/VB6 Syntax

`Public Declare Function CMS_GetSigDataDigest Lib "diCrPKI.dll" 
    (ByVal strHexDigest As String, ByVal nHexDigestLen As Long, 
    ByVal strFileIn As String, ByVal strCertFile As String, 
    ByVal nOptions As Long) As Long`

`nRet = CMS_GetSigDataDigest(strHexDigest, nHexDigestLen, strFileIn, 
    strCertFile, nOptions) As Long`

### C/C++ Syntax

`long __stdcall CMS_GetSigDataDigest(char *szOutput, long nOutChars, const char *szFileIn, const char *szCertFile, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive the message digest output.

*nOutChars*
:   [in] specifying the length of the output string.

*szFileIn*
:   [in] with name of signed-data CMS object file 
	or the data as a [base64 or PEM string](#cmsbase64pem).

*szCertFile*
:   [in] specifying an (optional) X.509 certificate file
to be used to identify the signer.

*nOptions*
:   [in] option flags:   

`PKI_DEFAULT` (0) for default options

### Returns (VBA/C)

If successful, the return value is a non-negative value indicating the message digest algorithm
(**CAUTION:** this is *not* the number of characters in the output);
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cmsGetSigDataDigest`](#VB_cmsGetSigDataDigest) (szFileIn As String, Optional szCertFile As String = "", Optional nOptions As Long = 0) As String

### .NET Equivalent

[Cms.GetSigDataDigest Method](#M_Cms_GetSigDataDigest)  

### C++ (STL) Equivalent

static std::string [dipki::Cms::GetSigDataDigest](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a6ae8fc70eebf1dbc348b7df0c1273bc6 "External link") (const std::string &inputFile, const std::string &certFile="")

### Remarks

This function extracts the message digest of the signed encapsulated content. 
In doing so, it also verifies that the signature is valid. 
The object may be a "detached signature" object.
If signed attributes are present, the function will extract the `messageDigest`
attribute for RSA and DSA signature algorithms. 
If signed attributes are not present, the message digest is extracted
directly from the signature value, but only for RSASSA-PKCS1-v1_5 signatures, 
as the message digest cannot be directly extracted from a DSA or RSA-PSS signature. 
If given, the function will use the public key from the specified X.509 certificate to validate the signature; 
otherwise it will use the first valid SignerInfo and certificate pair it finds in the SignedData.

The message digest, if found, is copied into *szHexDigest*.
The maximum expected length of *szHexDigest* is `PKI_MAX_HASH_CHARS` characters. 
ANSI C users [must add one to this value](#cusersaddone) when allocating memory.
The message digest is encoded in hexadecimal format using lower-case letters [a-f].

The message digest algorithm is indicated by the return code:

| Code | Algorithm |
| --- | --- |
| `PKI_HASH_SHA1` (0) | SHA-1 |
| `PKI_HASH_MD5` (1) | MD5 |
| `PKI_HASH_MD2` (2) | MD2 |
| `PKI_HASH_SHA256` (3) | SHA-256 |
| `PKI_HASH_SHA384` (4) | SHA-384 |
| `PKI_HASH_SHA512` (5) | SHA-512 |
| `PKI_HASH_SHA224` (6) | SHA-224 |

**CAUTION:** unlike other hash-related functions, this function does 
*not* return the length of the digest string;
it returns the code for the digest algorithm.  

Note that this *does not* verify that the message digest is that of the content.
It does, however, verify that the message digest was indeed signed by the purported signer, but it does not check the
content itself.
To verify that the SignedData object is validly signed, the user must extract the content separately
and verify that its message digest matches the digest extracted by this function.
To do this, use the functions
[`CMS_ReadSigDataToString()`](#CMS_ReadSigDataToString)
and [`HASH_HexFromBytes()`](#HASH_HexFromBytes).
VB6 users can use `HASH_HexFromString`. See the examples below.

Alternatively, use the 
[`CMS_VerifySigData()`](#CMS_VerifySigData)
to verify the signature and message digest directly and use 
[`CMS_QuerySigData()`](#CMS_QuerySigData) to extract the messageDigest attribute, if present,
without validation.

### Example (VBA core function)

This example extracts the message digest from the "detached signature" signed CMS object 
created by `CMS_MakeDetachedSig` above. 

```

Dim nDigAlg As Long
Dim strCMSFile As String
Dim strHexDigest As String
strCMSFile = "DetSignByAlice.bin"
strHexDigest = String(PKI_MAX_HASH_CHARS, " ")
nDigAlg = CMS_GetSigDataDigest(strHexDigest, Len(strHexDigest), strCMSFile, "", 0)
Debug.Print "CMS_GetSigDataDigest returns " & nDigAlg
If nDigAlg < 0 Then
    Exit Function
End If
Debug.Print "Extracted digest is"
Debug.Print "[" & strHexDigest & "]"

```

This should produce the output

```

CMS_GetSigDataDigest returns 0
Extracted digest is
[406aec085279ba6e16022d9e0629c0229687dd48]

```

This second example shows how to retrieve the message digest and independently
verify this against a hash of the content.

```

Dim strCMSFile As String
Dim strHexDigest As String
Dim nDigAlg As Long
Dim strData As String
Dim nDataLen As Long
Dim strContentDigest As String
Dim nHashLen As Long

strCMSFile = "4.2.bin"

' 1. Get the digest value
strHexDigest = String(PKI_MAX_HASH_CHARS, " ")
nDigAlg = CMS_GetSigDataDigest(strHexDigest, _
    Len(strHexDigest), strCMSFile, "", 0)
Debug.Print "CMS_GetSigDataDigest returns " & nDigAlg
If nDigAlg < 0 Then
    Exit Function
End If
Debug.Print "Extracted digest is"
Debug.Print "[" & strHexDigest & "]"

' 2. Go get the content - in this case it's in the signed-data object
nDataLen = CMS_ReadSigDataToString("", 0, strCMSFile, 0)
If nDataLen <= 0 Then
    Exit Function
End If
strData = String(nDataLen, " ")
nDataLen = CMS_ReadSigDataToString(strData, nDataLen, strCMSFile, 0)
Debug.Print "CMS_ReadSigDataToString returns " & nDataLen
Debug.Print "Data is [" & strData & "]"

' 3. Compute independently the hash of what we found
' (Note how we use the digest algorithm code returned above)
strContentDigest = String(PKI_MAX_HASH_CHARS, " ")
nHashLen = HASH_HexFromString(strContentDigest, _
    Len(strContentDigest), strData, nDataLen, nDigAlg)
Debug.Print "Computed hash of content is"
Debug.Print "[" & strContentDigest & "]"

' 4. Can we match this hash digest with 
'    what we extracted from the signed-data?
strContentDigest = Left(strContentDigest, nHashLen)
strHexDigest = Left(strHexDigest, nHashLen)
If strContentDigest = strHexDigest Then
    Debug.Print "SUCCESS - digests match!"
Else
    Debug.Print "FAILS! - no match"
End If

```

This should produce the output

```

CMS_GetSigDataDigest returns 0
Extracted digest is
[406aec085279ba6e16022d9e0629c0229687dd48]
CMS_ReadSigDataToString returns 28
Data is [This is some sample content.]
Computed hash of content is
[406aec085279ba6e16022d9e0629c0229687dd48]
SUCCESS - digests match!

```

And again, this time using C:

```

char *infile = "C:\\Test\\4.2.bin";
long ndigalg, mlen, hlen;
char hexdigest[41];
char conthash[41];
char *message;

/* 1. Get the digest string */
ndigalg = CMS_GetSigDataDigest(hexdigest, sizeof(hexdigest)-1, 
	infile, NULL, 0);
printf("CMS_GetSigDataDigest returns %ld\n", ndigalg);
if (ndigalg < 0) disp_error(ndigalg);
printf("SigDataDigest = %s\n", hexdigest);
//assert(lRet >= 0);

/* 2. Get the content from the signed-data object */
mlen = CMS_ReadSigDataToString(NULL, 0, infile, 0);
printf("Message data is %ld bytes long\n", mlen);
if (mlen < 0) disp_error(mlen);
assert(mlen >= 0);

/* Allocate some memory - NB add an extra byte */
message = malloc(mlen + 1);
assert(message);

/* Now read in */
mlen = CMS_ReadSigDataToString(message, mlen, infile, 0);
printf("CMS_ReadSigDataToString returns %ld\n", mlen);
if (mlen < 0) disp_error(mlen);
assert(mlen >= 0);
printf("Message is '%s'\n", message);

/* 3. Create a digest of this content 
   -- use the algorithm we got above */
hlen = HASH_HexFromBytes(conthash, sizeof(conthash)-1, 
	(unsigned char*)message, mlen, ndigalg);
printf("ContentDigest = %s\n", conthash);

/* 4. Finally we can compare */
if (strncmp(conthash, hexdigest, hlen) == 0)
	printf("SUCCESS - digests match!\n");
else
	printf("FAILS! - no match\n");

/* Clean up */
free(message);

```

### Example (VBA wrapper function)

```

Dim strHexDigest As String
Dim strData As String
Const strCMSFile As String = "4.2.bin"

' Extract the digest value
strHexDigest = cmsGetSigDataDigest(strCMSFile, "")
Debug.Print "extracted digest=[" & strHexDigest & "]"
' Extract content from signed-data file
strData = cmsReadSigDataToString(strCMSFile)
Debug.Print "content='" & strData & "'"
' Compute digest value over the content
Debug.Print "computed digest =[" & hashHexFromBytes(StrConv(strData, vbFromUnicode), PKI_HASH_SHA1) & "]"

```

### See Also

[CMS_ReadSigData](#CMS_ReadSigData)
[CMS_ReadSigDataToString](#CMS_ReadSigDataToString)
[CMS_QuerySigData](#CMS_QuerySigData)
[CMS_VerifySigData](#CMS_VerifySigData)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CMS_MakeComprData"></a>CMS_MakeComprData
-----------------------------------------------

Creates a new CMS compressed-data file (.p7z) from an existing input file.

### VBA/VB6 Syntax

`Public Declare Function CMS_MakeComprData Lib "diCrPKI.dll" (ByVal strFileOut As String, ByVal strFileIn As String, ByVal nOptions As Long) As Long`

`nRet = CMS_MakeComprData(strFileOut, strFileIn, nOptions) As Long`

### C/C++ Syntax

`long __stdcall CMS_MakeComprData(const char *szFileOut, const char *szFileIn, long nOptions);`

### Parameters

*szFileOut*
:   [in] name of output file to be created.

*szFileIn*
:   [in] name of file containing input data.

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a negative [error code](#errorcodes). 

### .NET Equivalent

[Cms.MakeComprData Method](#M_Cms_MakeComprData)  

### C++ (STL) Equivalent

static int [dipki::Cms::MakeComprData](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a872169f6f2c0e75785c6021a23cfce63 "External link") (const std::string &outputFile, const std::string &inputFile)

### Python Equivalent

static [Cms.make_comprdata](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.make_comprdata "External link")(outputfile, inputfile)

### Remarks

This creates a CMS compressed-data file (conventionally saved with a .p7z extension) using the `zlibCompress` algorithm.
It only works in file-to-file mode.
Any existing file with the same name as the parameter *szFileOut* will be overwritten without warning.
Note that it may not produce an exact identical output to that of another program on the same input
due to differences in ZLIB buffers and window sizes.

### Example

```

Dim nRet As Long
Dim strBaseFile As String
Dim strCompFile As String
Dim strChkFile As String
Dim strFileType As String

strBaseFile = "sonnets.txt"
strCompFile = "sonnets.p7z"

' Create a CMS compressed-data file
nRet = CMS_MakeComprData(strCompFile, strBaseFile, 0)
Debug.Print "CMS_MakeComprData returns " & nRet & " (expecting 0)"
Debug.Print "FileLen('" & strBaseFile & "')=" & FileLen(strBaseFile)
Debug.Print "FileLen('" & strCompFile & "')=" & FileLen(strCompFile)

' Check ASN.1 file type
strFileType = String(PKI_ASN1_TYPE_MAXCHARS, " ")
nRet = ASN1_Type(strFileType, Len(strFileType), strCompFile, 0)
Debug.Print "File Type='" & Left(strFileType, nRet) & "'"

' Now check we can read it
strChkFile = "sonnets-uncompr.txt"
nRet = CMS_ReadComprData(strChkFile, strCompFile, 0)
Debug.Print "CMS_ReadComprData returns " & nRet & " (expecting +ve)"

' And check with no-inflate option
strChkFile = "sonnets-noinflate.txt"
nRet = CMS_ReadComprData(strChkFile, strCompFile, PKI_CMS_NO_INFLATE)
Debug.Print "CMS_ReadComprData(PKI_CMS_NO_INFLATE) returns " & nRet & " (expecting +ve)"

```

```

CMS_MakeComprData returns 0 (expecting 0)
FileLen('sonnets.txt')=106081
FileLen('sonnets.p7z')=40862
File Type='PKCS7/CMS COMPRESSED DATA                                       '
CMS_ReadComprData returns 106081 (expecting +ve)
CMS_ReadComprData(PKI_CMS_NO_INFLATE) returns 40770 (expecting +ve)

```

### See Also

[CMS_ReadComprData](#CMS_ReadComprData)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CMS_MakeDetachedSig"></a>CMS_MakeDetachedSig
---------------------------------------------------

Creates a "detached signature" CMS signed-data object from a message
digest of the content.

### VBA/VB6 Syntax

`Public Declare Function CMS_MakeDetachedSig Lib "diCrPKI.dll" 
    (ByVal strFileOut As String, ByVal strHexDigest As String, 
    ByVal strCertList As String, ByVal strPrivateKey As String, 
    ByVal nOptions As Long) As Long`

`nRet = CMS_MakeDetachedSig(strFileOut, strHexDigest, 
    strCertList, strPrivateKey, nOptions) As Long`

### C/C++ Syntax

`long __stdcall CMS_MakeDetachedSig(const char *szFileOut, const char *szHexDigest, const char *szCertList, const char *szPrivateKey, long nOptions);`

### Parameters

*szFileOut*
:   [in] with name of output file to be created.

*szHexDigest*
:   [in] containing the digest of the content in hexadecimal format.

*szCertList*
:   [in] containing the filename of the signer's certificate and (optionally)
a list of other certificates to be included in the output, separated by semi-colons (`;`)

*szPrivateKey*
:   [in] containing the private key data for the signer.

*nOptions*
:   [in] option flags: 
Select one of:  

`PKI_HASH_SHA1` (0) to use the SHA-1 algorithm (default)  

`PKI_HASH_SHA224` to use the SHA-224 algorithm  

`PKI_HASH_SHA256` to use the SHA-256 algorithm  

`PKI_HASH_SHA384` to use the SHA-384 algorithm  

`PKI_HASH_SHA512` to use the SHA-512 algorithm  

and optionally add  

`PKI_CMS_EXCLUDE_CERTS` to exclude signer's certificate  

`PKI_CMS_INCLUDE_ATTRS` to add signed attributes (default = no signed attributes) including content-type and message-digest plus any more added below.  

`PKI_CMS_ADD_SIGNTIME` to add SigningTime to the signed attributes (requires `PKI_CMS_INCLUDE_ATTRS`)  

`PKI_CMS_ADD_SMIMECAP` to add sMIMECapabilities to the signed attributes (requires `PKI_CMS_INCLUDE_ATTRS`)  

`PKI_CMS_ADD_SIGNINGCERT` to add ESS Signing Certificate attribute to the signed attributes (requires `PKI_CMS_INCLUDE_ATTRS`)  

`PKI_CMS_FORMAT_BASE64` to format the output with base64 encoding (default output is binary)

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes). Further error information may be available by calling
[`PKI_LastError()`](#PKI_LastError).

### .NET Equivalent

[Cms.MakeDetachedSig Method](#M_Cms_MakeDetachedSig)  

### C++ (STL) Equivalent

static int [dipki::Cms::MakeDetachedSig](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a038c7a5e87adab4472215ace4b425312 "External link") (const std::string &outputFile, const std::string &hexDigest, const std::string &certList, const std::string &privateKey, SigAlg sigAlg=SigAlg::Default, SigDataOptions opts=SigDataOptions::Default_SigDataOpt, Format format=Format::Default)

### Python Equivalent

static [Cms.make_detached_sig](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.make_detached_sig "External link")(outputfile, hexdigest, certlist, prikeystr, sigalg=SigAlg.DEFAULT, opts=SigDataOpts.DEFAULT)

### Remarks

RSASSA-PKCS1V1_5 only.
See [`CMS_MakeSigData()`](#CMS_MakeSigData) for more details. 
The `PKI_CMS_EXCLUDE_DATA` option is obviously ignored.

### Example

This example creates a "detached signature" CMS signed-data object that would duplicate a "detached
signature" version of example 4.2 from  [[SMIME-EX]](#SMIME-EX) if they did one. 
It uses Alice's RSA private key to sign the SHA-1 Message digest of the content "This is some sample content.".
The output is a BER-encoded CMS signedData object which includes her certificate but has no signed attributes.

```

Dim nRet As Long
Dim strEPKFile As String
Dim strCertFile As String
Dim strOutFile As String
Dim strHexDigest As String
Dim strPrivateKey As String

strEPKFile = "AlicePrivRSASign.p8e"
strCertFile = "AliceRSASignByCarl.cer"
strOutFile = "DetSignByAlice.bin"
strHexDigest = "406aec085279ba6e16022d9e0629c0229687dd48"

' First, Alice reads her private key into a string
strPrivateKey = rsaReadPrivateKey(strEPKFile, "password")
If Len(strPrivateKey) = 0 Then
    MsgBox "Cannot read private key"
    Exit Function
End If

' Alice makes a detached signature using
' the hash of the content and her private key
nRet = CMS_MakeDetachedSig(strOutFile, strHexDigest, _
    strCertFile, strPrivateKey, 0)
Debug.Print "CMS_MakeDetachedSig returns " & nRet

```

### See Also

[CMS_MakeSigData](#CMS_MakeSigData)
[CMS_MakeSigDataFromString](#CMS_MakeSigDataFromString)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CMS_MakeEnvData"></a>CMS_MakeEnvData
-------------------------------------------

Create a CMS enveloped-data object for one or more recipients.

### VBA/VB6 Syntax

`Public Declare Function CMS_MakeEnvData Lib "diCrPKI.dll" 
    (ByVal strFileOut As String, ByVal strFileIn As String, 
    ByVal strCertList As String, ByVal strKeyString As String, ByVal nCount As Long, 
    ByVal nOptions As Long) As Long`

`nRet = CMS_MakeEnvData(strFileOut, strFileIn, 
    strCertList, strKeyString, nCount, nOptions) As Long`

### C/C++ Syntax

`long __stdcall CMS_MakeEnvData(const char *szFileOut, const char *szFileIn, const char *szCertList, const char *szKeyString, long nCount, long nOptions);`

### Parameters

*szFileOut*
:   [in] name of output file to be created.

*szFileIn*
:   [in] name of file containing input data.

*szCertList*
:   [in] list of one or more recipient X.509 certificate filenames, separated by semicolons (;). 
A certificate's representation in [base64](#base64forcert) or as a [PEM string](#pemstring) may be used instead of a filename.
Alternatively, specify a single PKCS#7 certificate chain file (.p7c/.p7b).

*Special cases:* Set as `"type=@pwri"` to create a single recipientInfo of the `PasswordRecipientInfo` (pwri) type; 
or set as `"type=@kekri,keyid=<string>"` to create a single recipientInfo of the `KEKRecipientInfo` (kekri) type. See Remarks.

*szKeyString*
:   [in] (formerly *szSeed*) Use to pass optional additional user key material (ukm) for KDF where KeyAgreement (kari) type is used.
Or use to pass the password for a pwri type or the key encryption key (KEK) for a kekri type.
Either pass a plain ASCII string or use the format `"#x<hex-digits>"` to pass a string of arbitrary octet values.
Required for pwri and kekri types.

Examples: `"abc"` will pass the 3 bytes (0x61, 0x62, 0x63);
`"#xdeadbeef01"` will pass the 5 bytes (0xde, 0xad, 0xbe, 0xef, 0x01).

*nCount*
:   [in] (formerly *nSeedLen*)
Optional iteration count for KDF in pwri type (default=4096) or tag length for AuthEnvelopedData (in range 12-16, default=16). Otherwise ignored.

*nOptions*
:   [in] option flags:
Set as zero (0) to use the defaults `rsaEncryption` for key transport or 
ECDH with ANSI-X9.63-KDF using SHA-1 with `cms3DESwrap` for key agreement; and
`aes128-CBC` for content encryption, and output in binary format.
**NOTE:** some default algorithms *[changed in v23.0]*  

To set the content encryption algorithm (default is `aes128-CBC`), add one of the following:  

`PKI_BC_AES128` to use `aes128-CBC` for content encryption (default as of [v23.0]) 

`PKI_BC_AES192` to use `aes192-CBC` for content encryption  

`PKI_BC_AES256` to use `aes256-CBC` for content encryption  

`PKI_BC_3DES` to use Triple-DES `des-EDE3-CBC` for content encryption [legacy]  

`PKI_AEAD_AES_128_GCM` to use `aes128-GCM` for content encryption and authentication  

`PKI_AEAD_AES_192_GCM` to use `aes192-GCM` for content encryption and authentication  

`PKI_AEAD_AES_256_GCM` to use `aes256-GCM` for content encryption and authentication  

`PKI_AEAD_CHACHA20_POLY1305` to use `AEAD_CHACHA20_POLY1305` for content encryption and authentication  

To set the key transport scheme or key encapsulation mechanism (KEM) for RSA, use one of 

`PKI_KT_RSAES_PKCS` (0) to encrypt the key using the RSAES-PKCS1-v1_5 encryption scheme `rsaEncryption` (default) 

`PKI_KT_RSAES_OAEP` to encrypt the key using the RSAES-OAEP encryption scheme (see [RSA signature and encryption schemes](#rsaschemes)).  

`PKI_KEM_RSA` *[New in v23.0]* to encrypt the key using the RSA Key Encapsulation Mechanism (RSA-KEM) algorithm
(see [RSA-KEM](#rsakem)).  

To select a hash function where applicable, add one of:  

`PKI_HASH_SHA1` to use SHA-1  (default - CAUTION)  

`PKI_HASH_SHA224` to use SHA-224  

`PKI_HASH_SHA256` to use SHA-256 [minimum recommended]  

`PKI_HASH_SHA384` to use SHA-384  

`PKI_HASH_SHA512` to use SHA-512  

If you have selected `PKI_KT_RSAES_OAEP` then, optionally, add  

`PKI_MGF_MGF1SHA1` to force the MGF hash function to be SHA-1 (default = same as encoding hash function set above)  

To set the key derivation function (KDF) (where applicable), add one of:  

`PKI_KDF_X963` to use the ANSI-X9.63-KDF key derivation function (default for ECDH).  

`PKI_KDF_HKDF` to use the HMAC-based Key Derivation Function (HKDF) from [[RFC5869](#RFC5869)]  

`PKI_KDF_KDF2` to use KDF2 from ANSI-X9.44 [[X9-44](#X9-44)]  

`PKI_KDF_KDF3` to use KDF3 from ANSI-X9.44 (default for RSA-KEM)  

and add the key wrap algorithm for the ECDH key agreement scheme or the kekri key encryption algorithm or RSA-KEM. 
Default (0) is to match the key agreement algorithm to the content encryption algorithm:  

`PKI_KWRAP_3DES` to use `cms3DESwrap` [legacy - only valid if Triple DES used for the content encryption algorithm].  

`PKI_KWRAP_AES128` to use `aes128-wrap`  

`PKI_KWRAP_AES192` to use `aes192-wrap`  

`PKI_KWRAP_AES256` to use `aes256-wrap`  

Optionally, add any of the bitflags:  

`PKI_CMS_FORMAT_BASE64` to encode the output with base64 encoding (default output is binary)  

`PKI_CMS_ALT_ALGID` to use specialist alternative encryption algorithm identifier (see Remarks)  

`PKI_CMS_BIGFILE` to speed up the processing of large files (binary file to binary file only)  

`PKI_CMS_USE_SKI` to use subjectKeyIdentifier (SKI) instead of issuerAndSerialNumber for RecipientInfo *[New in v23.0].*

### Returns (VBA/C)

If successful, the return value is the number of successful recipients;
otherwise it returns a negative [error code](#errorcodes). 

### VBA Wrapper Syntax

Public Function [`cmsMakeEnvData`](#VB_cmsMakeEnvData) (szFileOut As String, szFileIn As String, szCertList As String, Optional szKeyString As String = "", Optional nOptions As Long = 0, Optional nCount As Long = 0) As Long

### .NET Equivalent

[Cms.MakeEnvData Method](#M_Cms_MakeEnvData_StringStringStringCipherAlgorithmCms_EnvDataOptions) ( String, String, String, CipherAlgorithm, Cms.EnvDataOptions ) 

[Cms.MakeEnvData Method](#M_Cms_MakeEnvData_StringStringStringCipherAlgorithmCms_KeyEncrAlgorithmHashAlgorithmCms_EnvDataOptionsKdf_KdfAlgKdf_KeyWrapAlgStringInt32Cms_ContentEncrAlg) ( String, String, String, CipherAlgorithm, Cms.KeyEncrAlgorithm, HashAlgorithm, Cms.EnvDataOptions, Kdf.KdfAlg, Kdf.KeyWrapAlg, String, Int32, Cms.ContentEncrAlg ) 

### C++ (STL) Equivalent

static int [dipki::Cms::MakeEnvData](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a79d88f02853eff963ad194bf98d4bcd8 "External link") (const std::string &outputFile, const std::string &inputFile, const std::string &certList, CipherAlg cipherAlg=CipherAlg::Default, KeyEncrAlg keyEncrAlg=KeyEncrAlg::Default, HashAlg hashAlg=HashAlg::Default, EnvDataOptions advOpts=EnvDataOptions::Default_EnvDataOpt, Format format=Format::Default, bool bigFile=false, Kdf::KdfAlg kdfAlg=Kdf::KdfAlg::X963, Kdf::KeyWrapAlg keyWrapAlg=Kdf::KeyWrapAlg::Default, const std::string &keyString="", int count=0)  

static int [dipki::Cms::MakeEnvData](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#acf05de0c16ab1d1b7a0ed588f06fc20b "External link") (const std::string &outputFile, const std::string &inputFile, const std::string &schemeType, const std::string &keyString, CipherAlg cipherAlg=CipherAlg::Default, Kdf::KeyWrapAlg keyWrapAlg=Kdf::KeyWrapAlg::Default, EnvDataOptions advOpts=EnvDataOptions::Default_EnvDataOpt, Format format=Format::Default, HashAlg hashAlg=HashAlg::Default, int count=0)

### Python Equivalent

static [Cms.make_envdata](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.make_envdata "External link")(outputfile, inputfile, certlist, cipheralg=ContentEncrAlg.DEFAULT, keyencralg=KeyEncrAlg.DEFAULT, hashalg=0, opts=EnvDataOpts.DEFAULT, bigfile=False, kdfalg=Kdf.KdfAlg.X963, keywrapalg=0, keyString="", count=0)

### Remarks

The output is a file containing a CMS `EnvelopedData` or `AuthEnvelopedData` object which can be sent as part of an S/MIME message or used directly as a binary .p7m file. 
The supported objects are those described in [CMS Content Types](#supportedcmstypes).
RecipientInfo types can be `KeyTransRecipientInfo` (ktri), `KeyAgreeRecipientInfo` (kari), `KEKRecipientInfo` (kekri) and `PasswordRecipientinfo` (pwri). 
If the content encryption algorithm is an *authenticated* encryption algorithm (`AES*-GCM`), then the output will be an Authenticated-Enveloped-Data object (`AuthEnvelopedData`) as specified in
[[RFC5083](#RFC5083)] and [[RFC5084](#RFC5084)].

TL;DR. The RecipientInfo type will be set according to the type of public key in the X.509 certificates. If the certificate has an RSA key, then a key-transport RecipientInfo (ktri) will be created (default PKCS#1v1.5 or
RSA-OAEP if flag set). If the certificate contains a supported ECC public key, then a key-agreement type (kari) will be used (default ANSI-X9.63-KDF and keywrap to match the content encryption algorithm, HKDF if flag set).
You can pass a list of mixed certificates and the appropriate RecipientInfo type will be chosen for each.
There are special cases for KEK and password recipientInfo types - see below.

#### ktri and kari types

By default, the `RecipientInfo` type is set automatically depending on the public key found in each certificate in *szCertList*, 
one for each certificate. 
If the public key is RSA (rsaEncryption) then the key transport technique (ktri) will be used to create that particular `recipientInfo`. 
If the public key is a supported ECC key, then the standard ECDH ephemeral-static key agreement technique (kari) will be used as per [[RFC5753](#RFC5753)] and [[RFC8418](#RFC8418)].

No checks are made on the validity period of the recipients' X.509 certificates or their key usage attributes.
A PKCS#7 certificate chain file may be specified as an argument for *szCertList*.
In which case, all certificates in the chain file will be used as recipients.

It is an error if *any* specified certificate file in *szCertList* is missing or corrupted.
Call [PKI_LastError()](#PKI_LastError) to find more details of the errors that occurred.

#### kekri and pwri types

*[New in v20.6]*
RecipientInfo types `KEKRecipientInfo` (kekri) and `PasswordRecipientinfo` (pwri) are supported for a single recipient only.
For these types no certificates are required and the *szCertList* argument must include `"type=@kekri"` or `"type=@pwri"`, respectively, all characters lower case.
In addition, for a kekri type, this argument should be of the form `"type=@kekri,keyid=<string>"` (Note separated by a comma ',')
where the value for the keyid attribute is used to set the `keyIdentifier` field in the `KEKIdentifier`.
This can be a simple ASCII string or can use the format `"#x<hex-digits>"` to pass a string of arbitrary octet values. If omitted, the default `keyIdentifier` is "keyid".
Optionally add a `date` field in the `KEKIdentifier` by adding a `date=<iso-date-string>`, 
e.g. `"type=@kekri,keyid=ourkeyid,date=2022-07-31T12:01"`.

The *szKeyString* argument must include either the key encryption key (KEK) for kekri or the password for pwri.
This parameter is expected to be an ASCII string. A binary KEK may be passed by using the format `"#x<hex-digits>"` to pass a string of arbitrary octet values.

**Examples using szKeyString**

```

nRet = CMS_MakeEnvData("xscipher_kekri.p7m", "plain.txt", "type=@kekri,keyid=oursharedkey", 
    "#x0123456789ABCDEFF0E1D2C3B4A59687", 0, PKI_BC_AES192 Or PKI_KWRAP_AES128);

```

Creates an EnvelopedData file with a single recipientInfo of type `KEKRecipientInfo` (kekri) with a keyid of "oursharedkey" using the 128-bit KEK 
`(0x)0123456789ABCDEFF0E1D2C3B4A59687` wrapped with `aes128-wrap`. The content is encrypted with AES-192 using a random content encryption key.

```

nRet = CMS_MakeEnvData("xscipher_pwri.p7m", "plain.txt", "type=@pwri", 
    "This is my password", 6666, PKI_BC_AES256);

```

Creates an EnvelopedData file with a single recipientInfo of type `PasswordRecipientinfo` (pwri) using the password "This is my password". 
The iteration count for the KDF is 6666 (default=4096). The content is encrypted with AES-256 using a random content encryption key.

#### A note re order of fields:

*[New in v23.0]* recipientInfo fields will be sorted in strict DER set sorting order. 
This may not be in the order of the certificates passed in *szCertList*.

#### Other options

Use the `PKI_CMS_BIGFILE` option flag to handle large files more efficiently.
This results in improvements of speed typically of 30% and enables, in theory, unlimited sizes of enveloped files
(subject, of course, to your level of boredom in waiting for the output). Binary output only. Not available for authenticated encryption or kekri or pwri recipientInfo types.

**Specialist Option:** If the `PKI_CMS_ALT_ALGID` option flag is present, an alternative 
Content Encryption Algorithm Identifier will be used as follows:

| Default Content Encryption Algorithm Identifier | with `PKI_CMS_ALT_ALGID` |
| --- | --- |
| des-ede3-cbc (1.2.840.113549.3.7) | des_3CBC_pad (1.3.36.3.1.3.2.1) |

This alternative TeleTrusT algorithm identifier was added for compatibility with certain (superseded?) German Health profiles. 

### Example

The following example reproduces example 5.1 from  [[SMIME-EX](#SMIME-EX)].
It creates an `EnvelopedData` CMS object for Bob from the data file 
`excontent.txt` using Bob's X.509 certificate `BobRSASignByCarl.cer`.

```

Dim nRet As Long
Dim strOutputFile As String
Dim strInputFile As String
Dim strCertFile As String

strOutputFile = "cmsalice2bob.p7m"
strInputFile = "excontent.txt"
strCertFile = "BobRSASignByCarl.cer"
' This should return 1 (indicating one successful recipient)
nRet = CMS_MakeEnvData(strOutputFile, strInputFile, strCertFile, "", 0, 0)
Debug.Print "CMS_MakeEnvData returns " & nRet

```

Note that the output file will always be different from the smime-example
because the content-encryption key, IV and the encrypted-content will be different each time.

The next example does the same except for two recipients: Bob and Carl.

```

' This should return 2 (indicating two successful recipients)
nRet = CMS_MakeEnvData("cms2bobandcarl.p7m", "excontent.txt", _
    "BobRSASignByCarl.cer;CarlRSASelf.cer", "", 0, 0)
Debug.Print "CMS_MakeEnvData returns " & nRet

```

The third example is the same as the first, except it uses AES-128 instead of Triple-DES to encrypt the content.

```

nRet = CMS_MakeEnvData("cms2bob_aes128.p7m", "excontent.txt", _
    "BobRSASignByCarl.cer", "", 0, PKI_BC_AES128)
Debug.Print "CMS_MakeEnvData returns " & nRet

```

This example shows how to use the `PKI_CMS_BIGFILE` option.

```

Dim nRet As Long
Dim strEnvDataFile As String
Dim strInputFile As String
Dim strCheckFile As String
strEnvDataFile = "envbig.p7m"
strInputFile = "bigfile.txt"
Debug.Print "File " & strInputFile & "=" & FileLen(strInputFile) & " bytes"
' Make enveloped-data file: this should return 1 (indicating one successful recipient)
nRet = CMS_MakeEnvData(strEnvDataFile, strInputFile, "bob.cer;", "", 0, PKI_CMS_BIGFILE)
Debug.Print "CMS_MakeEnvData returns " & nRet & " (expected 1 => # recipients)"
' Now decrypt using Bob's private key
Dim strPrivateKey As String
strPrivateKey = rsaReadPrivateKey("bob.p8e", "password")
strCheckFile = strEnvDataFile & ".out.txt"
nRet = CMS_ReadEnvData(strCheckFile, strEnvDataFile, "", strPrivateKey, PKI_CMS_BIGFILE)
Debug.Print "CMS_ReadEnvData returns " & nRet & " (expected 0 => success)"
' Check file length
Debug.Print "File " & strCheckFile & "=" & FileLen(strCheckFile) & " bytes"

```

```

File bigfile.txt=10485700 bytes
CMS_MakeEnvData returns 1 (expected 1 => # recipients)
CMS_ReadEnvData returns 0 (expected 0 => success)
File envbig.p7m.out.txt=10485700 bytes

```

### Example (VBA wrapper function)

```

Dim n As Long
' Create an enveloped CMS object (ktri type) to Bob using Bob's RSA key...
n = cmsMakeEnvData("cms2bob_aes128.p7m", "excontent.txt", "BobRSASignByCarl.cer", "", PKI_BC_AES128 Or PKI_KT_RSAES_OAEP)
' Same but using authenticated encryption and creating an authEnvelopedData object...
n = cmsMakeEnvData("cms2bob_aes128auth.p7m", "excontent.txt", "BobRSASignByCarl.cer", "", PKI_AEAD_AES_128_GCM Or PKI_KT_RSAES_OAEP)
' Create an enveloped CMS object (kari type) to Dana using Dana's ECC key...
n = cmsMakeEnvData("cms2dana_hkdf.p7m", "excontent.txt", "lamps-dana.encrypt.crt", "", PKI_BC_AES256 Or PKI_HASH_SHA256 Or PKI_KDF_HKDF Or PKI_KWRAP_AES256)
' Create an enveloped CMS object (ktri + kari type) to Bob and Dana using respective RSA and ECC keys...
n = cmsMakeEnvData("cms2bob_dana.p7m", "excontent.txt", "BobRSASignByCarl.cer;lamps-dana.encrypt.crt", "", PKI_BC_AES256 Or PKI_KT_RSAES_OAEP Or PKI_HASH_SHA256 Or PKI_KDF_HKDF)
' Create an enveloped CMS object (kekri type) using a previously distributed symmetric key-encryption key (KEK)...
n = cmsMakeEnvData("cms_envdata_kekri.p7m", "excontent.txt", "type=@kekri,keyid=ourcommonkey", "#x0123456789ABCDEFF0E1D2C3B4A59687", PKI_BC_AES256 Or PKI_HASH_SHA256 Or PKI_KWRAP_AES128)
' Create an enveloped CMS object (pwri type) using password-based key management...
n = cmsMakeEnvData("cms_envdata_pwri.p7m", "excontent.txt", "type=@pwri", "password12345", PKI_BC_AES192)

```

### See Also

[CMS_MakeEnvDataFromString](#CMS_MakeEnvDataFromString)
[CMS_MakeEnvDataFromBytes](#CMS_MakeEnvDataFromBytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CMS_MakeEnvDataFromBytes"></a>CMS_MakeEnvDataFromBytes
-------------------------------------------------------------

Create a CMS enveloped-data object from data in a byte array. 

### VBA/VB6 Syntax

`Public Declare Function CMS_MakeEnvDataFromBytes Lib "diCrPKI.dll" (ByVal strFileOut As String, ByRef lpInput As Byte, ByVal nInputLen As Long, ByVal strCertList As String, ByVal strKeyString As String, ByVal nCount As Long, ByVal nOptions As Long) As Long`

`nRet = CMS_MakeEnvDataFromBytes(strFileOut, lpInput(0), nInputLen, strCertList, strKeyString, nCount, nOptions) As Long`

### C/C++ Syntax

`long __stdcall CMS_MakeEnvDataFromBytes(const char *szFileOut, const unsigned char *lpInput, long nInputLen, const char *szCertList, const char *szKeyString, long nCount, long nOptions);`

### Parameters

*szFileOut*
:   [in] name of output file to be created.

*lpInput*
:   [in] byte array containing the input data.

*nInputLen*
:   [in] length in bytes of input data.

*szCertList*
:   [in] list of one or more recipient X.509 certificate filenames, separated by semicolons (;). 
A certificate's representation in [base64](#base64forcert) or as a [PEM string](#pemstring) may be used instead of a filename.
Alternatively, specify a single PKCS#7 certificate chain file (.p7c/.p7b).

*Special cases:* Set as `"type=@pwri"` to create a single recipientInfo of the `PasswordRecipientInfo` (pwri) type; 
or set as `"type=@kekri,keyid=<string>"` to create a single recipientInfo of the `KEKRecipientInfo` (kekri) type. See Remarks.

*szKeyString*
:   [in] (formerly *szSeed*) Use to pass optional additional user key material (ukm) for KDF where KeyAgreement (kari) type is used.
Or use to pass the password for a pwri type or the key encryption key (KEK) for a kekri type.
Either pass a plain ASCII string or use the format `"#x<hex-digits>"` to pass a string of arbitrary octet values.
Required for pwri and kekri types.

Examples: `"abc"` will pass the 3 bytes (0x61, 0x62, 0x63);
`"#xdeadbeef01"` will pass the 5 bytes (0xde, 0xad, 0xbe, 0xef, 0x01).

*nCount*
:   [in] (formerly *nSeedLen*)
Optional iteration count for KDF in pwri type (default=4096) or tag length for AuthEnvelopedData (in range 12-16, default=16). Otherwise ignored.

*nSeedLen*
:   [in] formerly used for length of the seed string. No longer used. [IGNORED!]

*nOptions*
:   [in] option flags: see the options in [CMS_MakeEnvData](#CMS_MakeEnvData).

### Returns (VBA/C)

If successful, the return value is the number of successful recipients;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cmsMakeEnvDataFromBytes`](#VB_cmsMakeEnvDataFromBytes) (szFileOut As String, lpInput() As Byte, szCertList As String, Optional szKeyString As String = "", Optional nOptions As Long = 0, Optional nCount As Long = 0) As Long

### .NET Equivalent

[Cms.MakeEnvDataFromBytes Method](#M_Cms_MakeEnvDataFromBytes)  

### C++ (STL) Equivalent

static int [dipki::Cms::MakeEnvDataFromBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a8d245dbe1764362c0439b710e9dd344b "External link") (const std::string &outputFile, const dipki::bvec_t &data, const std::string &certList, CipherAlg cipherAlg=CipherAlg::Default, KeyEncrAlg keyEncrAlg=KeyEncrAlg::Default, HashAlg hashAlg=HashAlg::Default, EnvDataOptions advOpts=EnvDataOptions::Default_EnvDataOpt, Format format=Format::Default, Kdf::KdfAlg kdfAlg=Kdf::KdfAlg::X963, Kdf::KeyWrapAlg keyWrapAlg=Kdf::KeyWrapAlg::Default, const std::string &ukmString="")

### Python Equivalent

static [Cms.make_envdata_from_bytes](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.make_envdata_from_bytes "External link")(outputfile, inputdata, certlist, cipheralg=ContentEncrAlg.DEFAULT, keyencralg=KeyEncrAlg.DEFAULT, hashalg=0, opts=EnvDataOpts.DEFAULT, kdfalg=Kdf.KdfAlg.X963, keywrapalg=0, keyString="", count=0)

### Remarks

This function is the same as `CMS_MakeEnvData`
except the input data is in a byte array instead of a file.

See the remarks for [`CMS_MakeEnvData()`](#CMS_MakeEnvData) above. 

Use this function if the plaintext contains non-ASCII characters such as UTF-8 encoded.

### Example

This example creates an enveloped-data object in a file 'cmsalice2bob_utf8.p7m'. 
The input is UTF-8-encoded data with some non-ASCII characters that encode to more than one byte.
See [CMS_ReadEnvDataToBytes](#CMS_ReadEnvDataToBytes) for example code to read it.

```

Dim nRet As Long
Dim strEnvDataFile As String
Dim strData As String
Dim abData() As Byte
Dim nBytes As Long

' Input contains two non-ASCII characters:
'   U+00CD Latin capital letter I with acute, encodes as (0x) C3 8D
'   U+00F1 Latin small letter N with tilde, encodes as (0x) C3 B1
strData = "<doc><name c='es'>Íñigo</name></doc>"
' Convert Unicode string to UTF-8-encoded byte array
nBytes = CNV_UTF8BytesFromLatin1(ByVal 0&, 0, strData)
ReDim abData(nBytes - 1)
nBytes = CNV_UTF8BytesFromLatin1(abData(0), nBytes, strData)
Debug.Print "INPUT STR=""" & strData & """" & " (" & Len(strData) & " chars)"
Debug.Print "HEX(UTF8)=" & cnvHexStrFromBytes(abData) & " (" & UBound(abData) + 1 & " bytes)"

' Create a CMS enveloped-data object using RSA-OAEP and AES-128 for content encryption
strEnvDataFile = "cmsalice2bob_utf8.p7m"
nRet = CMS_MakeEnvDataFromBytes(strEnvDataFile, _
	abData(0), nBytes, "BobRSASignByCarl.cer", "", 0, PKI_KT_RSAES_OAEP Or PKI_BC_AES128)
' This should return 1 (indicating one successful recipient)
Debug.Print "CMS_MakeEnvDataFromBytes returns " & nRet & " (= # recipients)"
Debug.Assert nRet > 0
Debug.Print "Created enveloped-data file '" & strEnvDataFile & "'"

```

```

INPUT STR="<doc><name c='es'>Íñigo</name></doc>" (36 chars)
HEX(UTF8)=3C646F633E3C6E616D6520633D276573273EC38DC3B169676F3C2F6E616D653E3C2F646F633E (38 bytes)
CMS_MakeEnvDataFromBytes returns 1 (= # recipients)
Created enveloped-data file 'cmsalice2bob_utf8.p7m'

```

### See Also

[CMS_MakeEnvData](#CMS_MakeEnvData)
[CMS_MakeEnvDataFromString](#CMS_MakeEnvDataFromString)
[CMS_ReadEnvDataToBytes](#CMS_ReadEnvDataToBytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CMS_MakeEnvDataFromString"></a>CMS_MakeEnvDataFromString
---------------------------------------------------------------

Create a CMS enveloped-data object from an ASCII string.

### VBA/VB6 Syntax

`Public Declare Function CMS_MakeEnvDataFromString Lib "diCrPKI.dll" 
    (ByVal strFileOut As String, ByVal strDataIn As String, 
    ByVal strCertList As String, ByVal strKeyString As String, ByVal nCount As Long, 
    ByVal nOptions As Long) As Long`

`nRet = CMS_MakeEnvDataFromString(strFileOut, strDataIn, strCertList, strKeyString, nCount, nOptions) As Long`

### C/C++ Syntax

`long __stdcall CMS_MakeEnvDataFromString(const char *szFileOut, const char *szDataIn, const char *szCertList, const char *szKeyString, long nCount, long nOptions);`

### Parameters

*szFileOut*
:   [in] name of output file to be created.

*szDataIn*
:   [in] string containing input data.

*szCertList*
:   [in] list of one or more recipient X.509 certificate filenames, separated by semicolons (;). 
A certificate's representation in [base64](#base64forcert) or as a [PEM string](#pemstring) may be used instead of a filename.
Alternatively, specify a single PKCS#7 certificate chain file (.p7c/.p7b).

*Special cases:* Set as `"type=@pwri"` to create a single recipientInfo of the `PasswordRecipientInfo` (pwri) type; 
or set as `"type=@kekri,keyid=<string>"` to create a single recipientInfo of the `KEKRecipientInfo` (kekri) type. See Remarks.

*szKeyString*
:   [in] (formerly *szSeed*) Use to pass optional additional user key material (ukm) for KDF where KeyAgreement (kari) type is used.
Or use to pass the password for a pwri type or the key encryption key (KEK) for a kekri type.
Either pass a plain ASCII string or use the format `"#x<hex-digits>"` to pass a string of arbitrary octet values.
Required for pwri and kekri types.

Examples: `"abc"` will pass the 3 bytes (0x61, 0x62, 0x63);
`"#xdeadbeef01"` will pass the 5 bytes (0xde, 0xad, 0xbe, 0xef, 0x01).

*nCount*
:   [in] (formerly *nSeedLen*)
Optional iteration count for KDF in pwri type (default=4096) or tag length for AuthEnvelopedData (in range 12-16, default=16). Otherwise ignored.

*nOptions*
:   [in] option flags: see the options in [CMS_MakeEnvData](#CMS_MakeEnvData).

### Returns (VBA/C)

If successful, the return value is the number of successful recipients;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cmsMakeEnvDataFromString`](#VB_cmsMakeEnvDataFromString) (szFileOut As String, szInput As String, szCertList As String, Optional szKeyString As String = "", Optional nOptions As Long = 0, Optional nCount As Long = 0) As Long

### .NET Equivalent

[Cms.MakeEnvDataFromString Method](#M_Cms_MakeEnvDataFromString_StringStringStringCipherAlgorithmCms_EnvDataOptions) (String, String, String, CipherAlgorithm, Cms.EnvDataOptions)  

[Cms.MakeEnvDataFromString Method](#M_Cms_MakeEnvDataFromString_StringStringStringCipherAlgorithmCms_KeyEncrAlgorithmHashAlgorithmCms_EnvDataOptionsKdf_KdfAlgKdf_KeyWrapAlgStringInt32Cms_ContentEncrAlg) (String, String, String, CipherAlgorithm, Cms.KeyEncrAlgorithm, HashAlgorithm, Cms.EnvDataOptions, Kdf.KdfAlg, Kdf.KeyWrapAlg, String, Int32, Cms.ContentEncrAlg)  

### C++ (STL) Equivalent

static int [dipki::Cms::MakeEnvDataFromString](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a96b9276b195b0a13bde9fb2a0ecee69d "External link") (const std::string &outputFile, const std::string &inputStr, const std::string &certList, CipherAlg cipherAlg=CipherAlg::Default, KeyEncrAlg keyEncrAlg=KeyEncrAlg::Default, HashAlg hashAlg=HashAlg::Default, EnvDataOptions advOpts=EnvDataOptions::Default_EnvDataOpt, Format format=Format::Default, Kdf::KdfAlg kdfAlg=Kdf::KdfAlg::X963, Kdf::KeyWrapAlg keyWrapAlg=Kdf::KeyWrapAlg::Default, const std::string &ukmString="")

### Python Equivalent

static [Cms.make_envdata_from_string](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.make_envdata_from_string "External link")(outputfile, inputdata, certlist, cipheralg=ContentEncrAlg.DEFAULT, keyencralg=KeyEncrAlg.DEFAULT, hashalg=0, opts=EnvDataOpts.DEFAULT, kdfalg=Kdf.KdfAlg.X963, keywrapalg=0, keyString="", count=0)

### Remarks

This function is the same as `CMS_MakeEnvData`
except the input data is in an ASCII string instead of a file.

See the remarks for [`CMS_MakeEnvData()`](#CMS_MakeEnvData) above. 
Use this function only when the plaintext is only plain ASCII text,
otherwise use [CMS_MakeEnvDataFromBytes](#CMS_MakeEnvDataFromBytes).

### Example

The following example reproduces example 5.2 from SMIME-EX 
(as far as it can, because of the different random values used each time) 
passing the input data as a string. The output is always a new file.

```

' This should return 1 (indicating one successful recipient)
nRet = CMS_MakeEnvDataFromString("cmsalice2bob1.p7m", _
    "This is some sample content.", "BobRSASignByCarl.cer", "", 0, 0)
Debug.Print "CMS_MakeEnvDataFromString returns " & nRet

```

### Example (VBA wrapper function)

```

Dim strCertList As String
Dim strCmsFile As String
Dim nRet As Long
Dim strQuery As String

' Use Dana's X22519 certificate
strCmsFile = "dana_alice_hkdf.p7m"
strCertList = "lamps-dana.encrypt.crt"
' Use AES256 for content encryption and Ephemeral-Static ECDH key agreement using HKDF key derivation function with SHA-256 and aes256-wrap
nRet = cmsMakeEnvDataFromString(strCmsFile, "This is some sample content.", strCertList, "", PKI_BC_AES256 Or PKI_HASH_SHA256 Or PKI_KDF_HKDF Or PKI_KWRAP_AES256)
Debug.Print "cmsMakeEnvDataFromString returns " & nRet & " (expecting 1)"
' Query EnvelopedData file
Debug.Print "FILE: " & strCmsFile
strQuery = "contentEncryptionAlgorithm"
Debug.Print "QueryEnvData('" & strQuery & "')=" & cmsQueryEnvData(strCmsFile, strQuery)
strQuery = "keyEncryptionAlgorithm"
Debug.Print "QueryEnvData('" & strQuery & "')=" & cmsQueryEnvData(strCmsFile, strQuery)
strQuery = "keyWrapAlgorithm"
Debug.Print "QueryEnvData('" & strQuery & "')=" & cmsQueryEnvData(strCmsFile, strQuery)

```

```

cmsMakeEnvDataFromString returns 1 (expecting 1)
FILE: dana_alice_hkdf.p7m
QueryEnvData('contentEncryptionAlgorithm')=aes256-CBC
QueryEnvData('keyEncryptionAlgorithm')=ecdhHKDF-SHA256
QueryEnvData('keyWrapAlgorithm')=aes256-wrap

```

### See Also

[CMS_MakeEnvData](#CMS_MakeEnvData)
[CMS_MakeEnvDataFromBytes](#CMS_MakeEnvDataFromBytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CMS_MakeSigData"></a>CMS_MakeSigData
-------------------------------------------

Creates a CMS object of type SignedData from an input data file.

### VBA/VB6 Syntax

`Public Declare Function CMS_MakeSigData Lib "diCrPKI.dll" 
    (ByVal strFileOut As String, ByVal strFileIn As String, 
    ByVal strCertList As String, ByVal strPrivateKey As String, ByVal nOptions As Long) As Long`

`nRet = CMS_MakeSigData(strFileOut, strFileIn, strCertList, strPrivateKey, nOptions) As Long`

### C/C++ Syntax

`long __stdcall CMS_MakeSigData(const char *szFileOut, const char *szFileIn, const char *szCertList, const char *szPrivateKey, long nOptions);`

### Parameters

*szFileOut*
:   [in] name of output file to be created.

*szFileIn*
:   [in] name of file containing message data to be signed.

*szCertList*
:   [in] filename of the signer's certificate and (optionally)
a list of other certificates to be included in the output, separated by semi-colons (;).
Alternatively specify a single PKCS#7 certificate chain file (.p7c/.p7b) containing the signer's certificate.

*szPrivateKey*
:   [in] private key data for the sender in "internal" string format.

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_SIG_RSA_SHA1` (0) to use RSASSA-PKCS-v1_5 with SHA-1  (`sha1WithRSAEncryption`) (default - CAUTION)  

`PKI_SIG_RSA_SHA224` to use RSASSA-PKCS-v1_5 with SHA-224  (`sha224WithRSAEncryption`)  

`PKI_SIG_RSA_SHA256` to use RSASSA-PKCS-v1_5 with SHA-256  (`sha256WithRSAEncryption`) [minimum recommended]  

`PKI_SIG_RSA_SHA384` to use RSASSA-PKCS-v1_5 with SHA-384  (`sha384WithRSAEncryption`)  

`PKI_SIG_RSA_SHA512` to use RSASSA-PKCS-v1_5 with SHA-512  (`sha512WithRSAEncryption`)  

`PKI_SIG_RSA_MD5` to use RSASSA-PKCS-v1_5 with MD5 (`md5WithRSAEncryption`) [legacy, not recommended for new implementations]  

`PKI_SIG_RSA_PSS_SHA1` to use RSASSA-PSS with SHA-1  

`PKI_SIG_RSA_PSS_SHA224` to use RSASSA-PSS with SHA-224  

`PKI_SIG_RSA_PSS_SHA256` to use RSASSA-PSS with SHA-256  

`PKI_SIG_RSA_PSS_SHA384` to use RSASSA-PSS with SHA-384  

`PKI_SIG_RSA_PSS_SHA512` to use RSASSA-PSS with SHA-512  

`PKI_SIG_ECDSA_SHA1` to use `ecdsaWithSHA1`  

`PKI_SIG_ECDSA_SHA224` to use `ecdsaWithSHA224`  

`PKI_SIG_ECDSA_SHA256` to use `ecdsaWithSHA256`  

`PKI_SIG_ECDSA_SHA384` to use `ecdsaWithSHA384`  

`PKI_SIG_ECDSA_SHA512` to use `ecdsaWithSHA512`  

`PKI_SIG_ED25519` to use `Ed25519` *[New in v20.0]*  

`PKI_SIG_ED448` to use `Ed448` *[New in v22.0]*  

  

And optionally add any combination of the following flags:  

`PKI_CMS_EXCLUDE_CERTS` to exclude signer's certificate  

`PKI_CMS_EXCLUDE_DATA` to exclude the eContent data  

`PKI_CMS_CERTS_ONLY` to create a "certs-only" PKCS#7 certficate chain  

`PKI_CMS_USE_SKI` to use subjectKeyIdentifier (SKI) instead of issuerAndSerialNumber for SignerIdentifier *[New in v23.0].*  

`PKI_CMS_INCLUDE_ATTRS` to add signed attributes (default = no signed attributes) including content-type and message-digest plus any more added below.  

`PKI_CMS_FORMAT_BASE64` to format the output with base64 encoding (default output is binary)  

`PKI_CMS_NO_OUTER` to create a "naked" SignedData object with no outerContentInfo as permitted by PKCS#7 v1.6 (specialist option)  

`PKI_CMS_ALT_ALGID` to use an alternative signature algorithm identifier (see Remarks)  

`PKI_CMS_BIGFILE` to speed up the processing of large files (see Remarks)  

`PKI_PSS_SALTLEN_ZERO` to set the salt length to be zero (RSASSA-PSS only, default = same length as the output of the hash function)  

`PKI_MGF_MGF1SHA1` to force the MGF hash function to be SHA-1 (RSASSA-PSS only, default = same as signature hash function)  

`PKI_CMS_PSEUDOSIG` to create a create a "pseudo" SignedData object with a dummy placeholder signature (see Remarks)  

`PKI_CMS_ADD_SIGNER` to add a new signer to an existing SignedData object *[New in v23.0]* (see Remarks)  

  

If the `PKI_CMS_INCLUDE_ATTRS` option flag is included, optionally add any of the following:  

`PKI_CMS_ADD_SIGNTIME` to add SigningTime to the signed attributes (requires `PKI_CMS_INCLUDE_ATTRS`)  

`PKI_CMS_ADD_SMIMECAP` to add sMIMECapabilities to the signed attributes (requires `PKI_CMS_INCLUDE_ATTRS`)  

`PKI_CMS_ADD_SIGNINGCERT` to add an ESS Signing Certificate Attribute to the signed attributes (requires `PKI_CMS_INCLUDE_ATTRS`) *[New in v12.4]*  

`PKI_CMS_ADD_ALGPROTECT` to add an Algorithm Identifier Protection Attribute to the signed attributes (requires `PKI_CMS_INCLUDE_ATTRS`) *[New in v12.4]*

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes). Further error information may be available by calling
[`PKI_LastError()`](#PKI_LastError).

### .NET Equivalent

[Cms.MakeSigData Method](#M_Cms_MakeSigData_StringStringStringStringCms_SigAlgCms_SigDataOptions) ( String, String, String, String, Cms.SigAlg, Cms.SigDataOptions)  

[Cms.MakeSigData Method](#M_Cms_MakeSigData_StringStringStringStringHashAlgorithmCms_SigDataOptions) ( String, String, String, String, HashAlgorithm, Cms.SigDataOptions)  

### C++ (STL) Equivalent

static int [dipki::Cms::MakeSigData](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#af25430f2abccb6b40baa9e597f619369 "External link") (const std::string &outputFile, const std::string &inputFile, const std::string &certList, const std::string &privateKey, SigAlg sigAlg=SigAlg::Default, SigDataOptions opts=SigDataOptions::Default_SigDataOpt, Format format=Format::Default, bool bigFile=false)

### Python Equivalent

static [Cms.make_sigdata](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.make_sigdata "External link")(outputfile, inputfile, certlist, prikeystr, sigalg=SigAlg.DEFAULT, opts=SigDataOpts.DEFAULT, bigfile=False)

### Remarks

A SignedData CMS object with a single SignerInfo is created with the message data included by default in the eContent.

The signer's certificate *must* be included in the certificate list.
All certificates in the list will be included in the output by default. 
Signed attributes are not included by default but can be added by using the `PKI_CMS_INCLUDE_ATTRS` option flag (see below).
Unsigned attributes and attribute certificates are not supported.
The default signature algorithm is RSASSA-PKCS-v1_5 with SHA-1 (*SHA-1 caution!*). 
The message digest algorithm *always* matches the digest algorithm used in the signature.

The encapContentInfo eContentType is always `id-data`: other eContentTypes are not possible.
Only one SignerInfo can be included at one time, but *[New in v23.0]* 
additional SignerInfos can be added by calling this function second time passing an existing SignedData object as input and setting the `PKI_CMS_ADD_SIGNER` (see below).
*[New in v23.0]* The signer's public key can be referenced using either `issuerAndSerialNumber` (default)
or `subjectKeyIdentifier` (use the `PKI_CMS_USE_SKI` option).
If `subjectKeyIdentifier` is used then the CMSversion will be 3 and the relevant SignerInfo version will also be 3.
Otherwise the CMSVersion will be 1 and the SignerInfo structure also version 1.

It is an error (`NO_MATCH_ERROR`) if the private key does not match any certificate in the certificate list.

#### A note re order of fields

*[New in v23.0]* signerInfo and CertificateSet fields will be sorted in strict DER set sorting order. 
This may not be in the order of the certificates passed in *szCertList* or added using `PKI_CMS_ADD_SIGNER`.

#### Notes on options

**PKI_CMS_CERTS_ONLY:** To create a PKCS#7 certificate chain 
(a degenerate "certs-only" signed data object), include the option flag `PKI_CMS_CERTS_ONLY`.
The *szCertList* can contain references to any existing certificate files in any order, separated by semi-colons.
The *szFileIn* and *szPrivateKey* parameters are ignored and can be left empty. 
See the second example below.

**PKI_CMS_INCLUDE_ATTRS:**
Signed attributes are *not* included by default. To add signed attributes use the `PKI_CMS_INCLUDE_ATTRS` option flag.
This will add the content-type and message-digest attributes plus any other attributes specified using a `PKI_CMS_ADD_*` option.

**PKI_CMS_ADD_SIGNINGCERT:** *[New in v12.4]*
Include the `PKI_CMS_ADD_SIGNINGCERT` option to add an ESS Signing Certificate Attribute to the signed attributes.
This is required for B-level compliance with CAdES-BES [[CADES](#CADES)] and with ESS [[RFC2634](#RFC2634)] and [[RFC5035](#RFC5035)].

**PKI_CMS_ADD_ALGPROTECT:** *[New in v12.4]*
Include the `PKI_CMS_ADD_ALGPROTECT` option to add an Algorithm Protection Attribute to the signed attributes.
This is in accordance with  [[RFC6211](#RFC6211)].
If a CMS validator supports this attribute, then additional checks can be made against algorithm substitution attacks. 

**PKI_CMS_BIGFILE:**
Include the `PKI_CMS_BIGFILE` option to cope more efficiently with large files. 
This only works in binary-file-to-binary-file mode, and only for RSA signatures, but makes a significant difference in processing times.
The option flags 
`PKI_CMS_EXCLUDE_DATA`,
`PKI_CMS_CERTS_ONLY`,
`PKI_CMS_FORMAT_BASE64`, and
`PKI_CMS_NO_OUTER`
are not permitted with this option.

**PKI_CMS_ADD_SIGNER:** *[New in v23.0]*
To sign an existing SignedData object with another signature, use the `PKI_CMS_ADD_SIGNER` option and pass the existing 
SignedData object as the input data file. Pass the signer's certificate in *szCertList* (plus any additional certificates if required)
and the signer's private key string in *szPrivateKey*. 

**PKI_PSS_SALTLEN_ZERO:** *[New in v12.0]*
Include the `PKI_PSS_SALTLEN_ZERO` with an RSA-PSS scheme to set the salt length parameter to be zero. This results in a deterministic signature value.
The default salt length is otherwise *always* `hLen`, the length of the output of the hash function. 
There are no other salt length options available for this function.  See [RSA signature and encryption schemes](#rsaschemes).

**PKI_CMS_ALT_ALGID:**
If the `PKI_CMS_ALT_ALGID` option flag is present, an alternative 
Signature Algorithm Identifier will be used as follows (RSAES-PKCS-v1_5 only):

| Message Digest Algorithm | Default Signature Algorithm Identifier | Alternative ID with `PKI_CMS_ALT_ALGID` |
| --- | --- | --- |
| SHA-1 (default, `PKI_SIG_RSA_SHA1`) | rsaEncryption (1.2.840.113549.1.1) | sha1withRSAEncryption (1.2.840.113549.1.1.5) |
| MD5 (with `PKI_SIG_RSA_MD5`) | rsaEncryption (1.2.840.113549.1.1) | md5withRSAEncryption (1.2.840.113549.1.1.4) |
| SHA-224 (with `PKI_SIG_RSA_SHA224`) | rsaEncryption (1.2.840.113549.1.1) | sha224withRSAEncryption (1.2.840.113549.1.1.14) |
| SHA-256 (with `PKI_SIG_RSA_SHA256`) | rsaEncryption (1.2.840.113549.1.1) | sha256withRSAEncryption (1.2.840.113549.1.1.11) |
| SHA-384 (with `PKI_SIG_RSA_SHA384`) | rsaEncryption (1.2.840.113549.1.1) | sha384withRSAEncryption (1.2.840.113549.1.1.12) |
| SHA-512 (with `PKI_SIG_RSA_SHA512`) | rsaEncryption (1.2.840.113549.1.1) | sha512withRSAEncryption (1.2.840.113549.1.1.13) |

The default is to use the `rsaEncryption` identifier specified in Section 3.2 of [[CMSALG](#CMSALG)].

**PKI_CMS_PSEUDOSIG:** *[New in v20.2]*
Include the `PKI_CMS_PSEUDOSIG` option to create a create a "pseudo" SignedData object.
The idea here is that we create an intermediate file which has the same structure as a CMS SignedData object except the signature is a dummy placeholder. 
We use the term "pseudo" file here to describe this intermediate file.

This pseudo file has the same digest value as the final signed object (as the digest is not calculated over the final signature). 
We send this digest value to a signing authority (say, Aruba), they sign it, and send back the actual signature value. 
This can be substituted in the intermediate pseudo file to produce the final SignedData object (.p7m file)
using [CMS_MakeSigDataFromSigValue](#CMS_MakeSigDataFromSigValue) with the `PKI_CMS_PSEUDOSIG` option.
RSASSA-PKCS1V1_5 only. 

**Specialist Option:** If the `PKI_CMS_NO_OUTER` option flag is present, the output will be a "naked"
SignedData object without an `outerContentInfo`. 
This is not permitted by the CMS standard [[CMS]](#CMS)
but is allowed by PKCS#7 version 1.6 [[PKCS7-EXT](#PKCS7-EXT)].
Some profiles (e.g. Royal Thai Customs) require this.

### Example

This example duplicates example 4.2 from [[SMIME-EX]](#SMIME-EX). It uses Alice's RSA private key to sign the message
stored in the file excontent.txt (which contains the text "This is some sample content.").
The output is a binary BER-encoded CMS signedData object which includes her certificate and the data but has no signed attributes.
The output file should match the file 4.2.bin from [SMIME-EX]. 

```

Dim strPriFile As String
Dim strPrivateKey As String
Dim nIntKeyLen As Long
Dim nRet As Long
Dim strInputFile As String
Dim strOutputFile As String
Dim strCertFile As String

strPriFile = "AlicePrivRSASign.pri"
strCertFile = "AliceRSASignByCarl.cer"
strInputFile = "excontent.txt"
strOutputFile = "BasicSignByAlice.bin"

' First we need to read in the private key string
' NB: This version is not encrypted, so no password needed
nIntKeyLen = RSA_ReadAnyPrivateKey("", 0, strPriFile, "", 0)
Debug.Print "nIntKeyLen = " & nIntKeyLen
If nIntKeyLen <= 0 Then
    Debug.Print pkiGetLastError()
    MsgBox "Unable to retrieve private key"
    Exit Sub
End If
' Pre-dimension the string to receive data
strPrivateKey = String(nIntKeyLen, " ")
' Read in the Private Key
nRet = RSA_ReadAnyPrivateKey(strPrivateKey, nIntKeyLen, strPriFile, "", 0)
Debug.Print "Key size=" & RSA_KeyBits(strPrivateKey) & " bits"

' Now we can sign our message
nRet = CMS_MakeSigData(strOutputFile, strInputFile, strCertFile, strPrivateKey, 0)
Debug.Print "CMS_MakeSigData returns " & nRet

```

In this second example, we create a PKCS#7 certficate chain file containing Carl's and Alice's X.509 certificates.

```

Dim nRet As Long
Dim strOutputFile As String
Dim strCertList As String

' Make a list of certs separated by semi-colons (;)
strCertList = "CarlRSASelf.cer;" & "AliceRSASignByCarl.cer"
Debug.Print "CertList=" & strCertList
strOutputFile = "SigDataCertsOnly.p7c"

' Create a certs-only .p7c chain
nRet = CMS_MakeSigData(strOutputFile, "", strCertList, "", PKI_CMS_CERTS_ONLY)
Debug.Print "CMS_MakeSigData returns " & nRet
If nRet <> 0 Then Debug.Print pkiGetLastError()

```

### See Also

[CMS_MakeSigDataFromString](#CMS_MakeSigDataFromString)
[CMS_MakeSigDataFromSigValue](#CMS_MakeSigDataFromSigValue)
[CMS_MakeDetachedSig](#CMS_MakeDetachedSig)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CMS_MakeSigDataFromSigValue"></a>CMS_MakeSigDataFromSigValue
-------------------------------------------------------------------

Creates a CMS object of type SignedData using a pre-computed signature
value.

### VBA/VB6 Syntax

`Public Declare Function CMS_MakeSigDataFromSigValue Lib "diCrPKI.dll" 
    (ByVal strFileOut As String, ByRef lpSigValue As Byte, ByVal nSigLen As Long,
    ByRef lpData As Byte, ByVal nDataLen As Long,
    ByVal strCertList As String, ByVal nOptions As Long) As Long`

`nRet = CMS_MakeSigDataFromSigValue(strFileOut, lpSigValue(0), nSigLen,
    lpData(0), nDataLen, strCertList, nOptions) As Long  ' Note the "(0)" after the byte array parameters`

### C/C++ Syntax

`long __stdcall CMS_MakeSigDataFromSigValue(const char *szFileOut, const unsigned char *lpSigValue, long nSigLen, const unsigned char *lpData, long nDataLen, const char *szCertList, long nOptions);`

### Parameters

*szFileOut*
:   [in] name of output file to be created.

*lpSigValue*
:   [in] byte array containing the pre-computed signature.

*nSigLen*
:   [in] length of the signature value in bytes.

*lpData*
:   [in] byte array containing the data that has been signed (required).

*nDataLen*
:   [in] length of the data in bytes.

*szCertList*
:   [in] filename of the signer's certificate and (optionally)
a list of other certificates to be included in the output, separated by semi-colons (;).
Alternatively specify a single PKCS#7 certificate chain file (.p7c/.p7b) containing the signer's certificate.

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_HASH_SHA1` (0) to use the SHA-1 algorithm (default)  

`PKI_HASH_SHA224` to use the SHA-224 algorithm  

`PKI_HASH_SHA256` to use the SHA-256 algorithm  

`PKI_HASH_SHA384` to use the SHA-384 algorithm  

`PKI_HASH_SHA512` to use the SHA-512 algorithm  

`PKI_HASH_MD5` to use the MD5 algorithm  

and optionally add  

`PKI_CMS_EXCLUDE_CERTS` to exclude signer's certificate  

`PKI_CMS_FORMAT_BASE64` to format the output with base64 encoding (default output is binary)  

`PKI_CMS_NO_OUTER` to create a "naked" SignedData object with no outerContentInfo 
as permitted by PKCS#7 v1.6  

`PKI_CMS_ALT_ALGID` to use alternative signature algorithm identifiers (see Remarks for 
[`CMS_MakeSigData()`](#CMS_MakeSigData))  

`PKI_CMS_PSEUDOSIG` to create a SignedData object from a "pseudo" object (see Remarks).

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes). Further error information may be available by calling
[`PKI_LastError()`](#PKI_LastError).

### VBA Wrapper Syntax

Public Function [`cmsMakeSigDataFromSigValue`](#VB_cmsMakeSigDataFromSigValue) (szFileOut As String, lpSigValue() As Byte, lpInput() As Byte, szCertList As String, Optional nOptions As Long = 0) As Long

### .NET Equivalent

[Cms.MakeSigDataFromSigValue Method](#M_Cms_MakeSigDataFromSigValue) 

[Cms.MakeSigDataFromPseudo Method](#M_Cms_MakeSigDataFromPseudo) 

### C++ (STL) Equivalent

static int [dipki::Cms::MakeSigDataFromSigValue](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a5bb3e903055c1877483f9d4e912808a2 "External link") (const std::string &outputFile, const dipki::bvec_t &sigValue, const dipki::bvec_t &data, const std::string &certList, SigAlg sigAlg=SigAlg::Default, SigDataOptions opts=SigDataOptions::Default_SigDataOpt, Format format=Format::Default)

static [Cms.make_sigdata_from_sigvalue](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.make_sigdata_from_sigvalue "External link")(outputfile, sigvalue, data, certlist, sigalg=SigAlg.DEFAULT, opts=SigDataOpts.DEFAULT)  

static [Cms.make_sigdata_from_pseudo](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.make_sigdata_from_pseudo "External link")(outputfile, inputfile, sigvalue, opts=SigDataOpts.DEFAULT)

`static [Cms.make_sigdata_from_pseudo](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.make_sigdata_from_pseudo "External link")(outputfile, inputfile, sigvalue, opts=SigDataOpts.DEFAULT)`

### Python Equivalent

`static [Cms.make_sigdata_from_sigvalue](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.make_sigdata_from_sigvalue "External link")(outputfile, sigvalue, data, certlist, sigalg=SigAlg.DEFAULT, opts=SigDataOpts.DEFAULT)`

`static [Cms.make_sigdata_from_pseudo](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.make_sigdata_from_pseudo "External link")(outputfile, inputfile, sigvalue, opts=SigDataOpts.DEFAULT)`

### Remarks

This is a specialized option for a specific case where the RSA v1.5 signature value over the content has been computed separately (say, using a smart card) and the user requires this to be used inside a CMS signed-data object.

A SignedData CMS object with a single SignerInfo is created with the message data included in the eContent.
Signed attributes *cannot* be added. Unsigned attributes and attribute certificates are not supported.
The content *must* be included in the input using the *lpData* and *nDataLen* parameters.
Only RSASSA-PKCS-v1_5 signature schemes are supported by this function.
Only one message digest algorithm is used in each object. SHA-1 is used by default. 
Alternative hash algorithms can be used instead by adding the appropriate `PKI_HASH_` option flag (this must match the digest algorithm used to compute the signature). 
The content and the signature are checked before the output file is created. If the signature data is not valid,
or the data is not the data signed, or the certificate specified is not that of the signer, then
it will return SIGNATURE_ERROR (-22).

*[New in v12.2]* A PKCS#7 certificate chain file (.p7c/.p7b) may be specified as an argument for *szCertList*.
The signer's certificate can now exist anywhere in the certificate list (previously it had to be the first).

*[New in v20.2]* Use the `PKI_CMS_PSEUDOSIG` option to create a SignedData object from a "pseudo" object, created using
[CMS_MakeSigData](#CMS_MakeSigData) with the `PKI_CMS_PSEUDOSIG` option.

### Example

This example creates an identical SignedData file to example 4.2 from [[SMIME-EX]](#SMIME-EX).
In this case, the signature value has been generated separately, perhaps by a smart card with Alice's private
key details in it. The resulting file should be identical to the file `4.2.bin`.

```

Dim strDataHex As String
Dim strSigHex As String
Dim abData() As Byte
Dim abSigValue() As Byte
Dim nSigLen As Long
Dim nDataLen As Long
Dim strCertFile As String
Dim strCmsFile As String
Dim nRet As Long

' Data to be signed in hex format:
strDataHex = "54:68:69:73:20:69:73:20:73:6f:6d:65:20:73:61:6d" & _
    "70:6c:65:20:63:6f:6e:74:65:6e:74:2e"
' The signature (generated by the smart card) is:
strSigHex = "2F:23:82:D2:F3:09:5F:B8:0C:58:EB:4E:9D:BF:89:9A" & _
    "81:E5:75:C4:91:3D:D3:D0:D5:7B:B6:D5:FE:94:A1:8A" & _
    "AC:E3:C4:84:F5:CD:60:4E:27:95:F6:CF:00:86:76:75" & _
    "3F:2B:F0:E7:D4:02:67:A7:F5:C7:8D:16:04:A5:B3:B5" & _
    "E7:D9:32:F0:24:EF:E7:20:44:D5:9F:07:C5:53:24:FA" & _
    "CE:01:1D:0F:17:13:A7:2A:95:9D:2B:E4:03:95:14:0B" & _
    "E9:39:0D:BA:CE:6E:9C:9E:0C:E8:98:E6:55:13:D4:68" & _
    "6F:D0:07:D7:A2:B1:62:4C:E3:8F:AF:FD:E0:D5:5D:C7"
strCertFile = "AliceRSASignByCarl.cer"
strCmsFile = "BasicSignByAliceExternal.bin"

' Convert the hex strings into byte arrays (non-hex chars are stripped)
abData = cnvBytesFromHexStr(strDataHex)
abSigValue = cnvBytesFromHexStr(strSigHex)
' Compute lengths
nDataLen = UBound(abData) - LBound(abData) + 1
nSigLen = UBound(abSigValue) - LBound(abSigValue) + 1

' Create the signed-data file
nRet = CMS_MakeSigDataFromSigValue(strCmsFile, abSigValue(0), _
    nSigLen, abData(0), nDataLen, strCertFile, 0)
Debug.Print "CMS_MakeSigDataFromSigValue returns " & nRet

```

To compare the output file to the reference file, use the Windows FC command:

```

C:> FC BasicSignByAliceExternal.bin 4.2.bin

```

```

Comparing files BasicSignByAliceExternal.bin and 4.2.BIN
FC: no differences encountered

```

### See Also

[CMS_MakeSigData](#CMS_MakeSigData)
[CMS_MakeDetachedSig](#CMS_MakeDetachedSig)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CMS_MakeSigDataFromBytes"></a>CMS_MakeSigDataFromBytes
-------------------------------------------------------------

Create a CMS object of type SignedData from an array of bytes. 

### VBA/VB6 Syntax

`Public Declare Function CMS_MakeSigDataFromBytes Lib "diCrPKI.dll" (ByVal strFileOut As String, ByRef lpInput As Byte, ByVal nInputLen As Long, ByVal strCertList As String, ByVal strPrivateKey As String, ByVal nOptions As Long) As Long`

`nRet = CMS_MakeSigDataFromBytes(strFileOut, lpInput(0), nInputLen, strCertList, strPrivateKey, nOptions) As Long`

### C/C++ Syntax

`long __stdcall CMS_MakeSigDataFromBytes(const char *szFileOut, const unsigned char *lpInput, long nInputLen, const char *szCertList, const char *szPrivateKey, long nOptions);`

### Parameters

*szFileOut*
:   [in] name of output file to be created.

*lpInput*
:   [in] byte array containing input data to be signed.

*nInputLen*
:   [in] length in bytes of input data.

*szCertList*
:   [in] filename of the signer's certificate and (optionally)
a list of other certificates to be included in the output, separated by semi-colons (;).
Alternatively specify a single PKCS#7 certificate chain file (.p7c/.p7b) containing the signer's certificate.

*szPrivateKey*
:   [in] private key data for the sender in "internal" string format.

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_SIG_RSA_SHA1` (0) to use RSASSA-PKCS-v1_5 with SHA-1  (`sha1WithRSAEncryption`) (default - CAUTION)  

`PKI_SIG_RSA_SHA224` to use RSASSA-PKCS-v1_5 with SHA-224  (`sha224WithRSAEncryption`)  

`PKI_SIG_RSA_SHA256` to use RSASSA-PKCS-v1_5 with SHA-256  (`sha256WithRSAEncryption`) [minimum recommended]  

`PKI_SIG_RSA_SHA384` to use RSASSA-PKCS-v1_5 with SHA-384  (`sha384WithRSAEncryption`)  

`PKI_SIG_RSA_SHA512` to use RSASSA-PKCS-v1_5 with SHA-512  (`sha512WithRSAEncryption`)  

`PKI_SIG_RSA_MD5` to use RSASSA-PKCS-v1_5 with MD5 (`md5WithRSAEncryption`) [legacy, not recommended for new implementations]  

`PKI_SIG_RSA_PSS_SHA1` to use RSASSA-PSS with SHA-1  

`PKI_SIG_RSA_PSS_SHA224` to use RSASSA-PSS with SHA-224  

`PKI_SIG_RSA_PSS_SHA256` to use RSASSA-PSS with SHA-256  

`PKI_SIG_RSA_PSS_SHA384` to use RSASSA-PSS with SHA-384  

`PKI_SIG_RSA_PSS_SHA512` to use RSASSA-PSS with SHA-512  

`PKI_SIG_ECDSA_SHA1` to use `ecdsaWithSHA1`  

`PKI_SIG_ECDSA_SHA224` to use `ecdsaWithSHA224`  

`PKI_SIG_ECDSA_SHA256` to use `ecdsaWithSHA256`  

`PKI_SIG_ECDSA_SHA384` to use `ecdsaWithSHA384`  

`PKI_SIG_ECDSA_SHA512` to use `ecdsaWithSHA512`  

`PKI_SIG_ED25519` to use `Ed25519` *[New in v20.0]*  

`PKI_SIG_ED2448` to use `Ed448` *[New in v22.0]*  

  

and optionally add any of the following flags:  

`PKI_CMS_EXCLUDE_CERTS` to exclude signer's certificate  

`PKI_CMS_EXCLUDE_DATA` to exclude the eContent data  

`PKI_CMS_CERTS_ONLY` to create a "certs-only" PKCS#7 certficate chain  

`PKI_CMS_INCLUDE_ATTRS` to add signed attributes (default = no signed attributes) including content-type and message-digest plus any more added below.  

`PKI_CMS_FORMAT_BASE64` to format the output with base64 encoding (default output is binary)  

`PKI_CMS_NO_OUTER` to create a "naked" SignedData object with no outerContentInfo as permitted by PKCS#7 v1.6 (specialist option)  

`PKI_CMS_ALT_ALGID` to use an alternative signature algorithm identifier (see Remarks)  

`PKI_CMS_BIGFILE` to speed up the processing of large files (see Remarks)  

`PKI_PSS_SALTLEN_ZERO` to set the salt length to be zero (RSASSA-PSS only, default = same length as the output of the hash function)  

`PKI_MGF_MGF1SHA1` to force the MGF hash function to be SHA-1 (RSASSA-PSS only, default = same as signature hash function)  

  

If the `PKI_CMS_INCLUDE_ATTRS` option flag is included, optionally add any of the following:  

`PKI_CMS_ADD_SIGNTIME` to add SigningTime to the signed attributes (requires `PKI_CMS_INCLUDE_ATTRS`)  

`PKI_CMS_ADD_SMIMECAP` to add sMIMECapabilities to the signed attributes (requires `PKI_CMS_INCLUDE_ATTRS`)  

`PKI_CMS_ADD_SIGNINGCERT` to add an ESS Signing Certificate Attribute to the signed attributes (requires `PKI_CMS_INCLUDE_ATTRS`) *[New in v12.4]*  

`PKI_CMS_ADD_ALGPROTECT` to add an Algorithm Identifier Protection Attribute to the signed attributes (requires `PKI_CMS_INCLUDE_ATTRS`) *[New in v12.4]*

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes). Further error information may be available by calling
[`PKI_LastError()`](#PKI_LastError).

### VBA Wrapper Syntax

Public Function [`cmsMakeSigDataFromBytes`](#VB_cmsMakeSigDataFromBytes) (szFileOut As String, lpInput() As Byte, szCertList As String, szPrivateKey As String, Optional nOptions As Long = 0) As Long

### .NET Equivalent

[Cms.MakeSigDataFromBytes Method](#M_Cms_MakeSigDataFromBytes)  

### C++ (STL) Equivalent

static int [dipki::Cms::MakeSigDataFromBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#aafc0c8beaa5bb8e19d7242c9c6f79487 "External link") (const std::string &outputFile, const dipki::bvec_t &data, const std::string &certList, const std::string &privateKey, SigAlg sigAlg=SigAlg::Default, SigDataOptions opts=SigDataOptions::Default_SigDataOpt, Format format=Format::Default)

static [Cms.make_sigdata_from_bytes](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.make_sigdata_from_bytes "External link")(outputfile, inputdata, certlist, prikeystr, sigalg=SigAlg.DEFAULT, opts=SigDataOpts.DEFAULT)

### Python Equivalent

`static [Cms.make_sigdata_from_string](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.make_sigdata_from_string "External link")(outputfile, inputstr, certlist, prikeystr, sigalg=SigAlg.DEFAULT, opts=SigDataOpts.DEFAULT)`

static [Cms.make_sigdata_from_bytes](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.make_sigdata_from_bytes "External link")(outputfile, inputdata, certlist, prikeystr, sigalg=SigAlg.DEFAULT, opts=SigDataOpts.DEFAULT)

### Remarks

This function is identical to 
[`CMS_MakeSigData()`](#CMS_MakeSigData)
except the input is passed as a byte array instead of in a file.

See the remarks for [`CMS_MakeSigData`](#CMS_MakeSigData) above.

Use this function if the content contains non-ASCII characters such as UTF-8 encoded. 

### Example

This example creates an signed-data object in a file 'basicsignedbyalice_utf8.p7m'. 
The input is UTF-8-encoded data with some non-ASCII characters that encode to more than one byte. 
See  [`CMS_ReadSigDataToBytes`](#CMS_ReadSigDataToBytes) for example code to read it. 

```

    Dim nRet As Long
    Dim strSigDataFile As String
    Dim strData As String
    Dim abData() As Byte
    Dim nBytes As Long
    Dim strPrivateKey As String
    
    ' Input contains two non-ASCII characters:
    '   U+00CD Latin capital letter I with acute, encodes as (0x) C3 8D
    '   U+00F1 Latin small letter N with tilde, encodes as (0x) C3 B1
    strData = "<doc><name c='es'>Íñigo</name></doc>"
    ' Convert Unicode string to UTF-8-encoded byte array
    nBytes = CNV_UTF8BytesFromLatin1(ByVal 0&, 0, strData)
    ReDim abData(nBytes - 1)
    nBytes = CNV_UTF8BytesFromLatin1(abData(0), nBytes, strData)
    Debug.Print "INPUT STR=""" & strData & """" & " (" & Len(strData) & " chars)"
    Debug.Print "HEX(UTF8)=" & cnvHexStrFromBytes(abData) & " (" & UBound(abData) + 1 & " bytes)"
    
    '  We need Alice's private key
    strPrivateKey = rsaReadPrivateKey("AlicePrivRSASign.p8e", "password")
    If Len(strPrivateKey) = 0 Then
        MsgBox "Cannot read private key"
        Exit Sub
    End If
    
    ' Create a CMS signed-data object
    strSigDataFile = "basicsignedbyalice_utf8.p7m"
    nRet = CMS_MakeSigDataFromBytes(strSigDataFile, _
        abData(0), nBytes, "AliceRSASignByCarl.cer", strPrivateKey, PKI_SIG_RSA_PSS_SHA256)
    ' This should return 0 indicating success
    Debug.Print "CMS_MakeSigDataFromBytes returns " & nRet & " (expected 0)"
    Debug.Assert 0 = nRet
    Debug.Print "Created signed-data file '" & strSigDataFile & "'"

CleanUp:
    wipeString strPrivateKey

```

```

INPUT STR="<doc><name c='es'>Íñigo</name></doc>" (36 chars)
HEX(UTF8)=3C646F633E3C6E616D6520633D276573273EC38DC3B169676F3C2F6E616D653E3C2F646F633E (38 bytes)
CMS_MakeSigDataFromBytes returns 0 (expected 0)
Created signed-data file 'basicsignedbyalice_utf8.p7m'

```

### Example (VBA wrapper function)

```

Dim strSigDataFile As String
Dim strCertFile As String
Dim lpData() As Byte
Dim strPrivateKey As String
Dim strQuery As String
Dim r As Long
	
' Input contains two non-ASCII characters:
'   U+00CD Latin capital letter I with acute, encodes as (0x) C3 8D
'   U+00F1 Latin small letter N with tilde, encodes as (0x) C3 B1
' Convert Unicode string to UTF-8-encoded byte array to be signed
lpData = cnvUTF8BytesFromLatin1("<doc><name c='es'>Íñigo</name></doc>")
Debug.Print "HEX(data to be signed)=" & cnvToHex(lpData)
' Read in Dana's ED25519 private key
strPrivateKey = eccReadPrivateKey("lamps-dana.p8.pem", "")
strCertFile = "lamps-dana.crt"

' Create a CMS signed-data object
strSigDataFile = "signeddata-utf8-dana.p7m"
r = cmsMakeSigDataFromBytes(strSigDataFile, lpData, strCertFile, strPrivateKey, PKI_SIG_ED25519 Or PKI_CMS_INCLUDE_ATTRS Or PKI_CMS_ADD_SIGNINGCERT)

Debug.Print "cmsMakeSigDataFromBytes returns " & r & " (expected 0)"
Debug.Assert 0 = r
Debug.Print "FILE: " & strSigDataFile
' Query the signed-data object
strQuery = "signatureAlgorithm"
Debug.Print "QuerySigData('" & strQuery & "')=" & cmsQuerySigData(strSigDataFile, strQuery)
strQuery = "signingCertHash"
Debug.Print "QuerySigData('" & strQuery & "')=" & cmsQuerySigData(strSigDataFile, strQuery)
' Check thumbprint of cert, this should match the signingCertHash
Debug.Print "CertThumb=" & x509CertThumb(strCertFile)
' Read back the signed data
lpData = cmsReadSigDataToBytes(strSigDataFile)
Debug.Print "HEX(recovered content)=" & cnvToHex(lpData)

```

```

HEX(data to be signed)=3C646F633E3C6E616D6520633D276573273EC38DC3B169676F3C2F6E616D653E3C2F646F633E
cmsMakeSigDataFromBytes returns 0 (expected 0)
FILE: signeddata-utf8-dana.p7m
QuerySigData('signatureAlgorithm')=Ed25519
QuerySigData('signingCertHash')=4db09e5f691aeaf46bffa1dbd4719d5c3f529ca0
CertThumb=4db09e5f691aeaf46bffa1dbd4719d5c3f529ca0
HEX(recovered content)=3C646F633E3C6E616D6520633D276573273EC38DC3B169676F3C2F6E616D653E3C2F646F633E

```

### See Also

[CMS_MakeSigData](#CMS_MakeSigData)
[CMS_MakeSigDataFromString](#CMS_MakeSigDataFromString)
[CMS_MakeDetachedSig](#CMS_MakeDetachedSig)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CMS_MakeSigDataFromString"></a>CMS_MakeSigDataFromString
---------------------------------------------------------------

Create a CMS object of type SignedData from an input string.

### VBA/VB6 Syntax

`Public Declare Function CMS_MakeSigDataFromString Lib "diCrPKI.dll" 
    (ByVal strFileOut As String, ByVal strDataIn As String, 
    ByVal strCertList As String, ByVal strPrivateKey As String, ByVal nOptions As Long) As Long`

`nRet = CMS_MakeSigDataFromString(strFileOut, strDataIn, 
    strCertList, strPrivateKey, nOptions) As Long`

### C/C++ Syntax

`long __stdcall CMS_MakeSigDataFromString(const char *szFileOut, const char *szDataIn, const char *szCertList, const char *szPrivateKey, long nOptions);`

### Parameters

*szFileOut*
:   [in] name of output file to be created.

*szDataIn*
:   [in] string containing message data to be signed.

*szCertList*
:   [in] filename of the signer's certificate and (optionally)
a list of other certificates to be included in the output, separated by semi-colons (;).
Alternatively specify a single PKCS#7 certificate chain file (.p7c/.p7b) containing the signer's certificate.

*szPrivateKey*
:   [in] private key data for the sender in "internal" string format.

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_SIG_RSA_SHA1` (0) to use RSASSA-PKCS-v1_5 with SHA-1  (`sha1WithRSAEncryption`) (default - CAUTION)  

`PKI_SIG_RSA_SHA224` to use RSASSA-PKCS-v1_5 with SHA-224  (`sha224WithRSAEncryption`)  

`PKI_SIG_RSA_SHA256` to use RSASSA-PKCS-v1_5 with SHA-256  (`sha256WithRSAEncryption`) [minimum recommended]  

`PKI_SIG_RSA_SHA384` to use RSASSA-PKCS-v1_5 with SHA-384  (`sha384WithRSAEncryption`)  

`PKI_SIG_RSA_SHA512` to use RSASSA-PKCS-v1_5 with SHA-512  (`sha512WithRSAEncryption`)  

`PKI_SIG_RSA_MD5` to use RSASSA-PKCS-v1_5 with MD5 (`md5WithRSAEncryption`) [legacy, not recommended for new implementations]  

`PKI_SIG_RSA_PSS_SHA1` to use RSASSA-PSS with SHA-1  

`PKI_SIG_RSA_PSS_SHA224` to use RSASSA-PSS with SHA-224  

`PKI_SIG_RSA_PSS_SHA256` to use RSASSA-PSS with SHA-256  

`PKI_SIG_RSA_PSS_SHA384` to use RSASSA-PSS with SHA-384  

`PKI_SIG_RSA_PSS_SHA512` to use RSASSA-PSS with SHA-512  

`PKI_SIG_ECDSA_SHA1` to use `ecdsaWithSHA1`  

`PKI_SIG_ECDSA_SHA224` to use `ecdsaWithSHA224`  

`PKI_SIG_ECDSA_SHA256` to use `ecdsaWithSHA256`  

`PKI_SIG_ECDSA_SHA384` to use `ecdsaWithSHA384`  

`PKI_SIG_ECDSA_SHA512` to use `ecdsaWithSHA512`  

`PKI_SIG_ED25519` to use `Ed25519` *[New in v20.0]*  

`PKI_SIG_ED448` to use `Ed448` *[New in v22.0]*  

  

and optionally add any of the following flags:  

`PKI_CMS_EXCLUDE_CERTS` to exclude signer's certificate  

`PKI_CMS_EXCLUDE_DATA` to exclude the eContent data  

`PKI_CMS_CERTS_ONLY` to create a "certs-only" PKCS#7 certficate chain  

`PKI_CMS_INCLUDE_ATTRS` to add signed attributes (default = no signed attributes) including content-type and message-digest plus any more added below.  

`PKI_CMS_FORMAT_BASE64` to format the output with base64 encoding (default output is binary)  

`PKI_CMS_NO_OUTER` to create a "naked" SignedData object with no outerContentInfo as permitted by PKCS#7 v1.6 (specialist option)  

`PKI_CMS_ALT_ALGID` to use an alternative signature algorithm identifier (see Remarks)  

`PKI_PSS_SALTLEN_ZERO` to set the salt length to be zero (RSASSA-PSS only, default = same length as the output of the hash function)  

`PKI_MGF_MGF1SHA1` to force the MGF hash function to be SHA-1 (RSASSA-PSS only, default = same as signature hash function)  

  

If the `PKI_CMS_INCLUDE_ATTRS` option flag is included, optionally add any of the following:  

`PKI_CMS_ADD_SIGNTIME` to add SigningTime to the signed attributes (requires `PKI_CMS_INCLUDE_ATTRS`)  

`PKI_CMS_ADD_SMIMECAP` to add sMIMECapabilities to the signed attributes (requires `PKI_CMS_INCLUDE_ATTRS`)  

`PKI_CMS_ADD_SIGNINGCERT` to add an ESS Signing Certificate Attribute to the signed attributes (requires `PKI_CMS_INCLUDE_ATTRS`) *[New in v12.4]*  

`PKI_CMS_ADD_ALGPROTECT` to add an Algorithm Identifier Protection Attribute to the signed attributes (requires `PKI_CMS_INCLUDE_ATTRS`) *[New in v12.4]*

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes). Further error information may be available by calling
[`PKI_LastError()`](#PKI_LastError).

### .NET Equivalent

[Cms.MakeSigDataFromString Method](#M_Cms_MakeSigDataFromString_StringStringStringStringCms_SigAlgCms_SigDataOptions) (String, String, String, String, Cms.SigAlg, Cms.SigDataOptions)  

[Cms.MakeSigDataFromString Method](#M_Cms_MakeSigDataFromString_StringStringStringStringHashAlgorithmCms_SigDataOptions) (String, String, String, String, HashAlgorithm, Cms.SigDataOptions)  

### C++ (STL) Equivalent

static int [dipki::Cms::MakeSigDataFromString](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a013c817c056f71eb9e12eab5991a814d "External link") (const std::string &outputFile, const std::string &inputStr, const std::string &certList, const std::string &privateKey, SigAlg sigAlg=SigAlg::Default, SigDataOptions opts=SigDataOptions::Default_SigDataOpt, Format format=Format::Default)

### Remarks

This function is identical to 
[`CMS_MakeSigData()`](#CMS_MakeSigData)
except the input is passed as a string instead of in a file.

Zero-terminated ANSI data is expected in *szDataIn*. 
VB6 users: the string *szDataIn* must not contain a NUL (`Chr$(0)`) character.
To sign a messsage that contains binary or Unicode UTF-8 or UTF-16 data, use 
[`CMS_MakeSigDataFromBytes`](#CMS_MakeSigDataFromBytes).

### Example

```

nRet = CMS_MakeSigDataFromString(strOutputFile, "This is some sample content.", _
	strCertFile, strPrivateKey, 0)

```

### See Also

[CMS_MakeSigData](#CMS_MakeSigData)
[CMS_MakeSigDataFromBytes](#CMS_MakeSigDataFromBytes)
[CMS_MakeDetachedSig](#CMS_MakeDetachedSig)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CMS_QueryEnvData"></a>CMS_QueryEnvData
---------------------------------------------

Queries a CMS enveloped-data object file for selected information.

### VBA/VB6 Syntax

`Public Declare Function CMS_QueryEnvData Lib "diCrPKI.dll" 
    (ByVal strDataOut As String, ByVal nDataLen As Long, 
    ByVal strFileIn As String, ByVal strQuery As String, ByVal nOptions As Long) As Long`

`nRet = CMS_QueryEnvData(strDataOut, nDataLen, strFileIn, strQuery,
    nOptions) As Long`

### C/C++ Syntax

`long __stdcall CMS_QueryEnvData(char *szOutput, long nOutChars, const char *szFileIn, const char *szQuery, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive the output.

*nOutChars*
:   [in] specifying the length of the output string.

*szFileIn*
:   [in] with name of signed-data CMS object file
		or the data as a [base64 or PEM string](#cmsbase64pem).

*szQuery*
:   [in] specifying the query (see Remarks below).

*nOptions*
:   [in] option flags:   

`PKI_DEFAULT` (0) for default options  

`PKI_QUERY_GETTYPE` to return the type of data returned for a given query.

### Returns (VBA/C)

If successful, the return value is a positive integer indicating either the result itself 
(if the result is a number)
or the number of characters in the output string (if the query is looking for a string).
If the item queried cannot be found, the return value is zero.
If there is an error (e.g. an invalid signed-data file), it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cmsQueryEnvData`](#VB_cmsQueryEnvData) (szFileIn As String, szQuery As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Cms.QueryEnvData Method](#M_Cms_QueryEnvData)  

### C++ (STL) Equivalent

static std::string [dipki::Cms::QueryEnvData](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a8f8afaad52471d4c8d9998e20081da33 "External link") (const std::string &inputFile, const std::string &query)

### Python Equivalent

static [Cms.query_envdata](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.query_envdata "External link")(cmsfile, query)

### Remarks

This function queries a given EnvelopedData file for selected information. 
The query string is case-insensitive, so `"version"`, `"VERSION"` and `"VeRsIoN"` are all valid.

Valid queries are (case-insensitive): 

| Query String | Returns | Data Type |
| --- | --- | --- |
| `version` | envelopedData CMSVersion (`edVer`) value | Number |
| `recipientInfoVersion` | recipientInfo version (`riVer`) value | Number |
| `recipientInfoType` | Type of recipientInfo: `ktri`, `kari`, `kekri`, `pwri`, `ori` | String |
| `CountOfRecipientInfos` | Number of RecipientInfos included in the data | Number |
| `recipientIssuerName` | Distinguished Name of recipient's certificate issuer | String |
| `recipientSerialNumber` | serialNumber of recipient's certificate in hex format | String |
| `keyEncryptionAlgorithm` | keyEncryptionAlgorithm, e.g. `"rsaEncryption"` | String |
| `keyEncryptionFlags` | Bit flags used for the key encryption algorithm (ktri only) | Number |
| `SizeOfEncryptedKey` | Size (in bytes) of the EncryptedKey | Number |
| `encryptedKey` | EncryptedKey value encoded in hex | String |
| `oaepParams` | Parameters used for RSA-OAEP (if applicable). | String |
| `kemParams` | Parameters used for RSA-KEM (if applicable) *[New in v23.0]* | String |
| `keyWrapAlgorithm` | Key wrap algorithm, e.g. `"aes128-wrap"` (kari and kekri only) | String |
| `originatorKeyAlgorithm` | OriginatorPublicKey algorithm, e.g. `"ecPublicKey"` (kari only) | String |
| `originatorPublicKey` | OriginatorPublicKey publicKey value encoded in hex (kari only) | String |
| `keyid` | keyIdentifier for KEKRecipientInfo (kekri) type | String |
| `ukm` | User Keying Material (if applicable) *[New in v23.0]* | String |
| `contentEncryptionAlgorithm` | contentEncryptionAlgorithm, e.g. `"des-EDE3-CBC"` | String |
| `SizeOfEncryptedContent` | Size (in bytes) of the EncryptedContent | Number |
| `encryptedContent` | EncryptedContent encoded in hex | String |
| `iv` | Initialization vector for encrypted content encoded in hex | String |
| `HASsubjectKeyIdentifier` | 1 if recipientIdentifier is the CHOICE subjectKeyIdentifier; 0 if issuerAndSerialNumber *[New in v23.0]* | Number |
| `recipientIdentifier` | recipientIdentifier value encoded in hex *[New in v23.0]* | String |

By default, the function queries the first recipientInfo in the file. 
To query the Nth recipientInfo append "/N" to the query string, e.g.
`"recipientInfoVersion/2"` to find the version number of the second recipientInfo in the file.
The query `encryptedContent` may be slow to respond if the file is large. 

The "raw" VBA/C function behaves differently depending on whether the output is a string or a number. 
If the result data type is a number then it returns the value directly.
If the result is a string, then it sets *szOutput* and returns the number of characters in the string.
The required number of characters can be found by passing zero for *nOutChars* or a null string for *szOutput*.
ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

Note that the VBA wrapper function and the C#/`VB.NET` and C++ (STL) methods *always* return a string, which is different from the behaviour of the raw VB6/C function.

To find out the type of data returned for a given query, use the `PKI_QUERY_GETTYPE` option. 
The function will return either `PKI_QUERY_NUMBER` (1) or `PKI_QUERY_STRING` (2), 
	or a negative "invalid query" error.
For example

```

nRet = CMS_QueryEnvData("", 0, "", "version", PKI_QUERY_GETTYPE);

```

will return `PKI_QUERY_NUMBER`.

### Example (VBA core function)

This example queries information from various sample files.

```

Dim strCmsFile As String
Dim nRet As Long
Dim strOutput As String
Dim strQuery As String

' Pre-dimension output string
strOutput = String(64, " ")

strCmsFile = "5.1.bin"
Debug.Print "File " & strCmsFile & "..."
strQuery = "version"
nRet = CMS_QueryEnvData(vbNullString, 0, strCmsFile, strQuery, 0)
Debug.Print strQuery & "=" & nRet
strQuery = "contentEncryptionAlgorithm"
nRet = CMS_QueryEnvData(strOutput, Len(strOutput), strCmsFile, strQuery, 0)
If nRet > 0 Then
    Debug.Print strQuery & "=" & Left$(strOutput, nRet)
End If
strQuery = "sizeofEncryptedContent"
nRet = CMS_QueryEnvData(vbNullString, 0, strCmsFile, strQuery, 0)
Debug.Print strQuery & "=" & nRet
strQuery = "countOfRecipientInfos"
nRet = CMS_QueryEnvData(vbNullString, 0, strCmsFile, strQuery, 0)
Debug.Print strQuery & "=" & nRet
strQuery = "keyEncryptionAlgorithm"
nRet = CMS_QueryEnvData(strOutput, Len(strOutput), strCmsFile, strQuery, 0)
If nRet > 0 Then
    Debug.Print strQuery & "=" & Left$(strOutput, nRet)
End If
strQuery = "sizeofEncryptedKey"
nRet = CMS_QueryEnvData(vbNullString, 0, strCmsFile, strQuery, 0)
Debug.Print strQuery & "=" & nRet

strCmsFile = "5.2.bin"
Debug.Print "File " & strCmsFile & "..."
nRet = CMS_QueryEnvData(strOutput, Len(strOutput), strCmsFile, "version", 0)
Debug.Print "Version=" & nRet
nRet = CMS_QueryEnvData(strOutput, Len(strOutput), strCmsFile, "contentEncryptionAlgorithm", 0)
If nRet > 0 Then
    Debug.Print "contentEncryptionAlgorithm=" & Left$(strOutput, nRet)
End If

```

In this example, file 5.1.bin is CMS Version 0 with content encryption algorithm `des_EDE3-CBC`, and
file 5.2.bin is CMSVersion 2 with content encryption algorithm `rc2CBC`.

```

File 5.1.bin...
version=0
contentEncryptionAlgorithm=des-EDE3-CBC
sizeofEncryptedContent=32
countOfRecipientInfos=1
keyEncryptionAlgorithm=rsaEncryption
sizeofEncryptedKey=128
File 5.2.bin...
Version=2
contentEncryptionAlgorithm=rc2CBC

```

### Example (VBA wrapper function)

```

Dim strQuery As String
Dim strOutput As String
Dim strEnvDataFile As String

strEnvDataFile = "5.1.bin"
Debug.Print "FILE: " & strEnvDataFile
strQuery = "keyEncryptionAlgorithm"
strOutput = cmsQueryEnvData(strEnvDataFile, strQuery, 0)
Debug.Print strQuery & " ==> " & strOutput
strQuery = "contentEncryptionAlgorithm"
strOutput = cmsQueryEnvData(strEnvDataFile, strQuery, 0)
Debug.Print strQuery & " ==> " & strOutput
strQuery = "sizeofEncryptedContent"
strOutput = cmsQueryEnvData(strEnvDataFile, strQuery, 0)
Debug.Print strQuery & " ==> " & strOutput

```

### See Also

[CMS_ReadEnvData](#CMS_ReadEnvData)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CMS_QuerySigData"></a>CMS_QuerySigData
---------------------------------------------

Queries a CMS signed-data object file for selected information.

### VBA/VB6 Syntax

`Public Declare Function CMS_QuerySigData Lib "diCrPKI.dll" 
    (ByVal strDataOut As String, ByVal nDataLen As Long, 
    ByVal strFileIn As String, ByVal strQuery As String, ByVal nOptions As Long) As Long`

`nRet = CMS_QuerySigData(strDataOut, nDataLen, strFileIn, strQuery,
    nOptions) As Long`

### C/C++ Syntax

`long __stdcall CMS_QuerySigData(char *szOutput, long nOutChars, const char *szFileIn, const char *szQuery, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive the output.

*nOutChars*
:   [in] specifying the length of the output string.

*szFileIn*
:   [in] with name of signed-data CMS object file
	or the data as a [base64 or PEM string](#cmsbase64pem).

*szQuery*
:   [in] specifying the query (see Remarks below).

*nOptions*
:   [in] option flags:   

`PKI_DEFAULT` (0) for default options  

`PKI_QUERY_GETTYPE` to return the type of data returned for a given query.

### Returns (VBA/C)

If successful, the return value is a positive integer indicating either the result itself 
(if the result is a number)
or the number of characters in the output string (if the query is looking for a string).
If the item queried cannot be found, the return value is zero.
If there is an error (e.g. an invalid signed-data file), it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cmsQuerySigData`](#VB_cmsQuerySigData) (szFileIn As String, szQuery As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Cms.QuerySigData Method](#M_Cms_QuerySigData)  

### C++ (STL) Equivalent

static std::string [dipki::Cms::QuerySigData](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#ae57ff9120187189f447b47fce29aa05c "External link") (const std::string &inputFile, const std::string &query)

### Python Equivalent

static [Cms.query_sigdata](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.query_sigdata "External link")(cmsfile, query)

### Remarks

This function queries a given SignedData file for selected information. 
Only version 1 signed-data objects are fully supported. 
The function will attempt to query other versions but may not succeed.
Note that this function does not verify any data, including the messageDigest attribute, it just returns what it finds.
The query string is case-insensitive, so `"version"`, `"Version"` and `"VeRsIoN"` are all valid. 

Valid queries are (case-insensitive):

| Query String | Returns | Data Type |
| --- | --- | --- |
| `version` | signedData version (`sdVer`) value | Number |
| `eContentType` | ContentType of the EncapsulatedContentInfo, e.g. `"data"` | String |
| `HASeContent` | 1 if eContent is present; 0 if not | Number |
| `CountOfCertificates` | Number of certificates in the SignedData | Number |
| `CountOfSignerInfos` | Number of SignerInfos in the SignedData | Number |
| `CountOfDigestAlgs` | Number of DigestAlgorithmIdentifiers in the SignedData *[New in v23.0]* | Number |
| `certificate/N` | Nth certificate encoded in base64 *[New in v23.0]* | String |
| `signerInfoVersion` | signerInfo version (`siVer`) value | Number |
| `digestAlgorithm` | digestAlgorithm, e.g. `"sha1"` | String |
| `signatureAlgorithm` | signatureAlgorithm, e.g. `"rsaEncryption"` | String |
| `signatureValue` | Signature value encoded in hex | String |
| `HASsignedAttributes` | 1 if signedAttributes (authenticatedAttributes) are present; 0 if not | Number |
| `DigestOfSignedAttrs` | Computed digest over signed attributes, if present, using digestAlgorithm | String |
| `DigestOfeContent` | Computed digest over eContent, if present, using digestAlgorithm | String |
| `signingTime` | signingTime attribute in format `"2005-12-31 23:30:59"` | String |
| `messageDigest` | messageDigest attribute in hexadecimal format, if present | String |
| `pssParams` | Parameters used for RSA-PSS (if applicable). | String |
| `HASsigningCertificate` | 1 if an ESS signingCertificate is present; 0 if not. | Number |
| `signingCertHash` | certHash value of ESS signing certificate, if present, encoded in hex | String |
| `HASalgorithmProtection` | 1 if a cmsAlgorithmProtection attribute is present; 0 if not. | Number |
| `HASsubjectKeyIdentifier` | 1 if signerIdentifier is the CHOICE subjectKeyIdentifier; 0 if issuerAndSerialNumber *[New in v23.0]* | Number |
| `signerIdentifier` | signerIdentifier value encoded in hex *[New in v23.0]* | String |

By default, the function queries the first signerInfo in the file. 
To query the Nth signerInfo append "/N" to the query string, e.g.
`"signerInfoVersion/2"` to find the version number of the second signerInfo in the file.

*[New in v23.0]* The query `"certificate/N"` will output the Nth certificate in the CertificateSet (default N = 1) encoded in base64. 
Note that the length of an X.509 certificate is typically several hundred bytes.

The "raw" VBA/C function behaves differently depending on whether the output is a string or a number. 
If the result data type is a number then it returns the value directly.
If the result is a string, then it sets *szOutput* and returns the number of characters in the string.
The required number of characters can be found by passing zero for *nOutChars* or a null string for *szOutput*.
ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

Note that the VBA wrapper function and the C#/`VB.NET` methods *always* return a string, which is different from the behaviour of the raw VB6/C function.

To find out the type of data returned for a given query, use the `PKI_QUERY_GETTYPE` option. 
The function will return either `PKI_QUERY_NUMBER` (1) or `PKI_QUERY_STRING` (2), 
	or a negative "invalid query" error.
For example

```

nRet = CMS_QuerySigData("", 0, "", "version", PKI_QUERY_GETTYPE);

```

will return `PKI_QUERY_NUMBER`.

### Example (VBA core function)

This example queries information from various sample files.

```

Dim strCMSFile As String
Dim nRet As Long
Dim strOutput As String

' Pre-dimension output string
strOutput = String(64, " ")

strCMSFile = "4.6.bin"
nRet = CMS_QuerySigData(strOutput, Len(strOutput), strCMSFile, "version", 0)
Debug.Print "Version=" & nRet

strCMSFile = "4.7.bin"
nRet = CMS_QuerySigData(strOutput, Len(strOutput), strCMSFile, "version", 0)
Debug.Print "Version=" & nRet
nRet = CMS_QuerySigData(strOutput, Len(strOutput), strCMSFile, "signingTime", 0)
If nRet > 0 Then
    Debug.Print "signingTime=" & Left$(strOutput, nRet)
Else
    Debug.Print "ERROR=" & nRet
End If

strCMSFile = "BasicSignByAlice_attr.bin"
nRet = CMS_QuerySigData(strOutput, Len(strOutput), strCMSFile, "signingTime", 0)
If nRet > 0 Then
    Debug.Print "signingTime=" & Left$(strOutput, nRet)
Else
    Debug.Print "ERROR=" & nRet
End If

```

In this example, file 4.6.bin is CMS Version 1, file 4.7.bin is CMS Version 3 with no signingTime attribute 
(if not present, it returns error code zero),
and the file BasicSignByAlice_attr.bin was signed at 7:31 a.m. on 25th February 2006:

```

Version=1
Version=3
ERROR=0
signingTime=2006-02-25 07:31:01

```

### Example (VBA wrapper function)

```

Dim strCMSFile As String
Dim strQuery As String
Dim strOutput As String

strCMSFile = "4.6.bin"
Debug.Print "FILE: " & strCMSFile
strQuery = "version"
strOutput = cmsQuerySigData(strCMSFile, strQuery)
Debug.Print strQuery & " ==> [" & strOutput & "]"
strQuery = "digestAlgorithm"
strOutput = cmsQuerySigData(strCMSFile, strQuery)
Debug.Print strQuery & " ==> [" & strOutput & "]"

strCMSFile = "4.7.bin"
Debug.Print "FILE: " & strCMSFile
strQuery = "version"
strOutput = cmsQuerySigData(strCMSFile, strQuery)
Debug.Print strQuery & " ==> [" & strOutput & "]"
strQuery = "signatureAlgorithm"
strOutput = cmsQuerySigData(strCMSFile, strQuery)
Debug.Print strQuery & " ==> [" & strOutput & "]"

strCMSFile = "BasicSignByAlice_attr.bin"
Debug.Print "FILE: " & strCMSFile
strQuery = "signingTime"
strOutput = cmsQuerySigData(strCMSFile, strQuery)
Debug.Print strQuery & " ==> [" & strOutput & "]"
```

### See Also

[CMS_ReadSigData](#CMS_ReadSigData)
[CMS_GetSigDataDigest](#CMS_GetSigDataDigest)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CMS_ReadComprData"></a>CMS_ReadComprData
-----------------------------------------------

Read and extract the decompressed contents of a CMS compressed-data file.

### VBA/VB6 Syntax

`Public Declare Function CMS_ReadComprData Lib "diCrPKI.dll" (ByVal strFileOut As String, ByVal strFileIn As String, ByVal nOptions As Long) As Long`

`nRet = CMS_ReadComprData(strFileOut, strFileIn, nOptions) As Long`

### C/C++ Syntax

`long __stdcall CMS_ReadComprData(const char *szFileOut, const char *szFileIn, long nOptions);`

### Parameters

*szFileOut*
:   [in] name of output file to be created.

*szFileIn*
:   [in] name of file containing input data.

*nOptions*
:   [in] option flags:  

`PKI_DEFAULT` (0) for default options  

`PKI_CMS_NO_INFLATE` to extract the compressed data as is without inflation

### Returns (VBA/C)

If successful, the return value is the number of bytes in the output file;
otherwise it returns a negative [error code](#errorcodes). 

### .NET Equivalent

[Cms.ReadComprData Method](#M_Cms_ReadComprData)  

### C++ (STL) Equivalent

static int [dipki::Cms::ReadComprData](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#af369d8fd68584480f57befcd10117261 "External link") (const std::string &outputFile, const std::string &inputFile, ComprDataOptions opts=ComprDataOptions::Default_ComprDataOpt)

### Python Equivalent

static [Cms.read_comprdata](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.read_comprdata "External link")(outputfile, inputfile, opts=ComprDataOpts.DEFAULT)

### Remarks

This will read and extract the contents of a CMS compressed-data file (conventionally saved with a .p7z extension) 
which uses the `zlibCompress` algorithm.
It only works in file-to-file mode.
Any existing file with the same name as the parameter *szFileOut* will be overwritten without warning.
Use the `PKI_CMS_NO_INFLATE` option to extract the compressed data as is without inflation.

### Example

See example in [CMS_MakeComprData](#CMS_MakeComprData).

### See Also

[CMS_MakeComprData](#CMS_MakeComprData)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CMS_ReadEnvData"></a>CMS_ReadEnvData
-------------------------------------------

Read and decrypt a CMS enveloped-data object to a file.

### VBA/VB6 Syntax

`Public Declare Function CMS_ReadEnvData Lib "diCrPKI.dll" 
    (ByVal strFileOut As String, ByVal strFileIn As String, 
    ByVal strCertFile As String, ByVal strPrivateKey As String, 
    ByVal nOptions As Long) As Long`

`nRet = CMS_ReadEnvData(strFileOut, strFileIn, 
    strCertFile, strPrivateKey, nOptions) As Long`

### C/C++ Syntax

`long __stdcall CMS_ReadEnvData(const char *szFileOut, const char *szFileIn, const char *szCertFile, const char *szPrivateKey, long nOptions);`

### Parameters

*szFileOut*
:   [in] with name of output file to be created.

*szFileIn*
:   [in] with name of file containing input data (binary or base64-encoded)
	or the data as a [base64 or PEM string](#cmsbase64pem).

*szCertFile*
:   [in] (optional) specifies the filename of the recipient's
X.509 certificate.

*szPrivateKey*
:   [in] recipient's private key in internal string format.

*nOptions*
:   [in] option flags:  

`PKI_DEFAULT` (0) for default options.  

`PKI_CMS_BIGFILE` to speed up the processing of large files (binary only).

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

[Cms.ReadEnvDataToFile Method](#M_Cms_ReadEnvDataToFile)  

### C++ (STL) Equivalent

static int [dipki::Cms::ReadEnvDataToFile](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#afad6be6e9ab0199d8a8a4143f731f6f6 "External link") (const std::string &outputFile, const std::string &inputFile, const std::string &privateKey, const std::string &certFile="", bool bigFile=false)

### Python Equivalent

static [Cms.read_envdata_to_file](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.read_envdata_to_file "External link")(outputfile, inputfile, prikeystr, certfile="", bigfile=False)

### Remarks

If received as an attachment to an S/MIME email message, the user must first extract the CMS object from the email
(*Hint:* use a text editor and cut out the base64 data from the message 
- see [Sending an enveloped-data object](#usinginmime) and work backwards).

The optional certificate *szCertFile* is used to identify the intended recipient in a message addressed to multiple
recipients. 
If the intended recipient's certificate is not provided, the first valid message that can be decrypted using the given private key, if any, will be extracted.

The supported `EnvelopedData` and `AuthEnvelopedData` objects are those described in [CMS Content Types](#supportedcmstypes).

Use the `PKI_CMS_BIGFILE` option to process large files more efficiently.
See the example in [`CMS_MakeEnvData()`](#CMS_MakeEnvData).

*[Changes in v12.1]* To avoid certain attacks that rely on timing differences, the encrypted content will *always* be decrypted.
If all else is good but no valid content encryption key (CEK) can be found in the recipient data, then a random key will be used.
The end result in this latter case will always be a negative `DECRYPT_ERROR` with no further information as to the cause.
If there is something obviously wrong with the *input*, such as a badly-formed input file (`INVALID_DATA_ERROR`), 
or the given certificate does not have a match with any recipient (`NO_MATCH_ERROR`), 
then an appropriate error code will be returned.

### Example

The following example reads the file created with [`CMS_MakeEnvData`](#CMS_MakeEnvData) above.
Bob's private key needs to be read into a string first
(see [`RSA_ReadEncPrivateKey`](#RSA_ReadEncPrivateKey)). 
The output is written directly to a new file.

```

Dim nRet As Long
Dim strFileIn As String
Dim strFileOut As String
Dim strPrivateKey As String

' Bob reads his private key into a string
strPrivateKey = rsaReadPrivateKey("BobPrivRSAEncrypt.p8e", "password")
If Len(strPrivateKey) = 0 Then
    MsgBox "Cannot read private key"
    Exit Function
End If

' Decrypt the input file; send plaintext to new output file
strFileIn = "cmsalice2bob.p7m"
strFileOut = "fromalice.txt"
nRet = CMS_ReadEnvData(strFileOut, strFileIn, "", strPrivateKey, 0)
Debug.Print "CMS_ReadEnvData returns " & nRet

' Clean up
WIPE_String strPrivateKey, Len(strPrivateKey)
strPrivateKey = ""

```

### See Also

[CMS_ReadEnvDataToString](#CMS_ReadEnvDataToString)
[CMS_MakeEnvDataFromString](#CMS_MakeEnvDataFromString)
[CMS_MakeEnvData](#CMS_MakeEnvData)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CMS_ReadEnvDataToBytes"></a>CMS_ReadEnvDataToBytes
---------------------------------------------------------

Reads and decrypts CMS enveloped-data object using the recipient's private key
writing the plaintext data directly into a byte array.

### VBA/VB6 Syntax

`Public Declare Function CMS_ReadEnvDataToBytes Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByVal strFileIn As String, ByVal strCertFile As String, ByVal strPrivateKey As String, ByVal nOptions As Long) As Long`

`nRet = CMS_ReadEnvDataToBytes(lpOutput(0), nOutBytes, strFileIn, strCertFile, strPrivateKey, nOptions) As Long`

### C/C++ Syntax

`long __stdcall CMS_ReadEnvDataToBytes(unsigned char *lpOutput, long nOutBytes, const char *szFileIn, const char *szCertFile, const char *szPrivateKey, long nOptions);`

### Parameters

*lpOutput*
:   [out] buffer to receive output plaintext.

*nOutBytes*
:   [in] length in bytes of the output buffer.

*szFileIn*
:   [in] name of file containing input data (binary or base64-encoded)
	or the data as a [base64 or PEM string](#cmsbase64pem).

*szCertFile*
:   [in] (optional) filename of the recipient's X.509 certificate.

*szPrivateKey*
:   [in] recipient's private key in internal string format.

*nOptions*
:   [in] option flags:  

`PKI_DEFAULT` (0) for default options

### Returns (VBA/C)

If successful, the return value is the number of bytes in the decrypted plaintext;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cmsReadEnvDataToBytes`](#VB_cmsReadEnvDataToBytes) (szFileIn As String, szCertFile As String, szPrivateKey As String, Optional nOptions As Long = 0) As Byte()

### .NET Equivalent

[Cms.ReadEnvDataToBytes Method](#M_Cms_ReadEnvDataToBytes)  

### C++ (STL) Equivalent

static bvec_t [dipki::Cms::ReadEnvDataToBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#adf858b4035b5091bbd9cdf6161f364f3 "External link") (const std::string &inputFile, const std::string &privateKey, const std::string &certFile="")

### Python Equivalent

static [Cms.read_envdata_to_bytes](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.read_envdata_to_bytes "External link")(inputfile, prikeystr, certfile="")

### Remarks

See the remarks for [`CMS_ReadEnvData()`](#CMS_ReadEnvData) above.
Call the function with a NULL *lpOutput* or zero *nOutBytes* parameter to find out the required length of
the output buffer.
Alternatively, use the [`CMS_QueryEnvData()`](#CMS_QueryEnvData)
function with the query `"sizeofEncryptedContent"`. 
This will return an upper bound on the length of the decrypted plaintext, at most 16 bytes too long.
Calling `CMS_ReadEnvDataToString()` with a properly-sized output buffer will return the exact size of the
recovered plaintext.
The buffer must be large enough to receive the entire output or a `SHORT_BUF_ERROR` error will result.

Use this function if the output plaintext is known to contain non-ASCII characters such as UTF-8 encoded.

### Example (VBA core function)

The following example reads the file created with [`CMS_MakeEnvDataFromBytes`](#CMS_MakeEnvDataFromBytes) above.
Bob's private key needs to be read into a string first
(see [`RSA_ReadAnyPrivateKey`](#RSA_ReadAnyPrivateKey)). 
The UTF-8-encoded output is written into a byte array, then converted to a VB Unicode string.

```

    Dim strEnvDataFile As String
    Dim strData As String
    Dim abData() As Byte
    Dim nBytes As Long
    Dim strPrivateKey As String
    Dim nChars As Long
    
    ' Read encrypted content from file
    strEnvDataFile = "cmsalice2bob_utf8.p7m"
    
    '  Read in Bob's encrypted private key
    strPrivateKey = rsaReadPrivateKey("BobPrivRSAEncrypt.p8e", "password")
    If Len(strPrivateKey) = 0 Then
        MsgBox "Cannot read private key"
        Exit Sub
    End If

    ' Find required length
    nBytes = CMS_ReadEnvDataToBytes(ByVal 0&, 0, strEnvDataFile, "", strPrivateKey, 0)
    Debug.Print "CMS_ReadEnvDataToBytes returns " & nBytes
    If nBytes <= 0 Then
        MsgBox "CMS_ReadEnvDataToBytes FAILED"
        GoTo CleanUp
    End If
    ' Dimension byte array to receive data
    ReDim abData(nBytes - 1)
    ' Extract the plaintext data
    nBytes = CMS_ReadEnvDataToBytes(abData(0), nBytes, strEnvDataFile, "", strPrivateKey, 0)
    Debug.Print "HEX(PT)=" & cnvHexStrFromBytes(abData)
    ' Convert from UTF-8 to VB Unicode string
    nChars = CNV_Latin1FromUTF8Bytes(0, 0, abData(0), nBytes)
     If nChars <= 0 Then
        MsgBox "CNV_Latin1FromUTF8Bytes FAILED"
        GoTo CleanUp
    End If
    strData = String(nChars, " ")
    nChars = CNV_Latin1FromUTF8Bytes(strData, nChars, abData(0), nBytes)
    Debug.Print "PT=" & strData
    
CleanUp:
    wipeString strPrivateKey

```

```

CMS_ReadEnvDataToBytes returns 38
HEX(PT)=3C646F633E3C6E616D6520633D276573273EC38DC3B169676F3C2F6E616D653E3C2F646F633E
PT=<doc><name c='es'>Íñigo</name></doc>

```

### Example (VBA wrapper function)

```

Dim strPrivateKey As String
Dim lpData() As Byte
Dim strData As String

' Read in private key to internal key string
strPrivateKey = rsaReadPrivateKey("BobPrivRSAEncrypt.p8e", "password")
Debug.Assert Len(strPrivateKey) > 0

' 1. Decrypted content is UTF-8 encoded
lpData = cmsReadEnvDataToBytes("cmsalice2bob_utf8.p7m", "", strPrivateKey, 0)
Debug.Assert cnvBytesLen(lpData) > 0
Debug.Print "HEX(PT)=" & cnvHexStrFromBytes(lpData)
' Convert from UTF-8-encoded bytes to VB Unicode string
strData = cnvLatin1FromUTF8Bytes(lpData)
Debug.Print "PT=" & strData

' 2. Decrypted content is plain ANSI string
strData = cmsReadEnvDataToString("cms2bobandcarl.p7m", "", strPrivateKey, 0)
Debug.Print "PT=" & strData

' Clean up
strPrivateKey = wipeString(strPrivateKey)

```

### See Also

[CMS_ReadEnvData](#CMS_ReadEnvData)
[CMS_ReadEnvDataToBytes](#CMS_ReadEnvDataToBytes)
[CMS_MakeEnvDataFromString](#CMS_MakeEnvDataFromString)
[CMS_MakeEnvData](#CMS_MakeEnvData)
[CMS_QueryEnvData](#CMS_QueryEnvData)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CMS_ReadEnvDataToString"></a>CMS_ReadEnvDataToString
-----------------------------------------------------------

Reads and decrypts CMS enveloped-data object using the recipient's private key
writing the plaintext data directly into a string.

### VBA/VB6 Syntax

`Public Declare Function CMS_ReadEnvDataToString Lib "diCrPKI.dll" 
    (ByVal strDataOut As String, ByVal nDataLen As Long, 
    ByVal strFileIn As String, ByVal strCertFile As String, 
    ByVal strPrivateKey As String, ByVal nOptions As Long) As Long`

`nRet = CMS_ReadEnvDataToString(strDataOut, nDataLen, strFileIn, 
    strCertFile, strPrivateKey, nOptions) As Long`

### C/C++ Syntax

`long __stdcall CMS_ReadEnvDataToString(char *szOutput, long nOutChars, const char *szFileIn, const char *szCertFile, const char *szPrivateKey, long nOptions);`

### Parameters

*szOutput*
:   [out] buffer to receive output plaintext.

*nOutChars*
:   [in] length in bytes of the output buffer.

*szFileIn*
:   [in] name of file containing input data (binary or base64-encoded)
	or the data as a [base64 or PEM string](#cmsbase64pem).

*szCertFile*
:   [in] (optional) filename of the recipient's
X.509 certificate.

*szPrivateKey*
:   [in] recipient's private key in internal string format.

*nOptions*
:   [in] option flags:  

`PKI_DEFAULT` (0) for default options

### Returns (VBA/C)

If successful, the return value is the number of bytes in the decrypted plaintext;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cmsReadEnvDataToString`](#VB_cmsReadEnvDataToString) (szFileIn As String, szCertFile As String, szPrivateKey As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Cms.ReadEnvDataToString Method](#M_Cms_ReadEnvDataToString)  

### Python Equivalent

static [Cms.read_envdata_to_string](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.read_envdata_to_string "External link")(inputfile, prikeystr, certfile="")

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

See the remarks for [`CMS_ReadEnvData()`](#CMS_ReadEnvData) above.

Alternatively, use the [`CMS_QueryEnvData()`](#CMS_QueryEnvData)
function with the query `"sizeofEncryptedContent"`. 
This will return an upper bound on the length of the decrypted plaintext, at most 16 bytes too long.
Calling `CMS_ReadEnvDataToString()` with a properly-sized output buffer will return the exact size of the
recovered plaintext.
The buffer must be large enough to receive the entire output or a `SHORT_BUF_ERROR` error will result.

Use this function only if the output plaintext is known to be plain ASCII text with no embedded NUL (zero) characters, 
otherwise use [CMS_ReadEnvDataToBytes](#CMS_ReadEnvDataToBytes).

### Example (VBA core function)

The following example reads the file created with [`CMS_MakeEnvData`](#CMS_MakeEnvData) above.
Bob's private key needs to be read into a string first
(see [`RSA_ReadAnyPrivateKey`](#RSA_ReadAnyPrivateKey)). 
The output is written into a string.

```

    Dim strPrivateKey As String
    Dim strFileIn As String
    Dim strDataOut As String
    Dim nLen As Long
    Dim strCertFile As String
    
    strFileIn = "cms2bobandcarl.p7m"
    
    ' First, Bob reads his private key into a string
    strPrivateKey = rsaReadPrivateKey("BobPrivRSAEncrypt.p8e", "password")
    If Len(strPrivateKey) = 0 Then
        MsgBox "Cannot read private key"
        Exit Sub
    End If
    
    ' Query the size of encrypted content (no need for an output buffer)
    nLen = CMS_QueryEnvData("", 0, strFileIn, "sizeofEncryptedContent", 0)
    Debug.Print "CMS_QueryEnvData returns " & nLen
    
    If nLen <= 0 Then
        GoTo CleanUp
    End If
    
    ' Pre-dimension string and read in the plaintext
    ' The final plaintext will always be shorter than the encrypted content.
    strDataOut = String(nLen, " ")
    nLen = CMS_ReadEnvDataToString(strDataOut, nLen, _
        strFileIn, "", strPrivateKey, 0)
    Debug.Print "CMS_ReadEnvDataToString returns " & nLen
    If nLen > 0 Then
        ' Fix correct size for final, unpadded plaintext
        strDataOut = Left(strDataOut, nLen)
        Debug.Print "Plaintext is '" & strDataOut & "'"
    End If
    
CleanUp:
    WIPE_String strPrivateKey, Len(strPrivateKey)
    strPrivateKey = ""

```

### Example (VBA wrapper function)

```

Dim strPrivateKey As String
Dim lpData() As Byte
Dim strData As String

' Read in private key to internal key string
strPrivateKey = rsaReadPrivateKey("BobPrivRSAEncrypt.p8e", "password")
Debug.Assert Len(strPrivateKey) > 0

' 1. Decrypted content is UTF-8 encoded
lpData = cmsReadEnvDataToBytes("cmsalice2bob_utf8.p7m", "", strPrivateKey, 0)
Debug.Assert cnvBytesLen(lpData) > 0
Debug.Print "HEX(PT)=" & cnvHexStrFromBytes(lpData)
' Convert from UTF-8-encoded bytes to VB Unicode string
strData = cnvLatin1FromUTF8Bytes(lpData)
Debug.Print "PT=" & strData

' 2. Decrypted content is plain ANSI string
strData = cmsReadEnvDataToString("cms2bobandcarl.p7m", "", strPrivateKey, 0)
Debug.Print "PT=" & strData

' Clean up
strPrivateKey = wipeString(strPrivateKey)

```

### See Also

[CMS_ReadEnvData](#CMS_ReadEnvData)
[CMS_ReadEnvDataToBytes](#CMS_ReadEnvDataToBytes)
[CMS_MakeEnvDataFromString](#CMS_MakeEnvDataFromString)
[CMS_MakeEnvData](#CMS_MakeEnvData)
[CMS_QueryEnvData](#CMS_QueryEnvData)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CMS_ReadSigData"></a>CMS_ReadSigData
-------------------------------------------

Reads the content from a CMS signed-data object file.

### VBA/VB6 Syntax

`Public Declare Function CMS_ReadSigData Lib "diCrPKI.dll" 
    (ByVal strFileOut As String, ByVal strFileIn As String, 
    ByVal nOptions As Long) As Long`

`nRet = CMS_ReadSigData(strFileOut, strFileIn, 
    nOptions) As Long`

### C/C++ Syntax

`long __stdcall CMS_ReadSigData(const char *szFileOut, const char *szFileIn, long nOptions);`

### Parameters

*szFileOut*
:   [in] with name of output file to be created.

*szFileIn*
:   [in] with name of signed-data CMS object file (binary or base64-encoded)
	or the data as a [base64 or PEM string](#cmsbase64pem).

*nOptions*
:   [in] option flags:   

`PKI_DEFAULT` (0) for default options  

`PKI_CMS_BIGFILE` to speed up the processing of large files (binary input only).

### Returns (VBA/C)

If successful, the return value is a positive number indicating the number of bytes in the content;
otherwise it returns a negative [error code](#errorcodes).

### .NET Equivalent

[Cms.ReadSigDataToFile Method](#M_Cms_ReadSigDataToFile)  

### C++ (STL) Equivalent

static int [dipki::Cms::ReadSigDataToFile](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a7bd1e326ed04aac001b35514bc1e1a89 "External link") (const std::string &outputFile, const std::string &inputFile, bool bigFile=false)

### Python Equivalent

static [Cms.read_sigdata_to_file](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.read_sigdata_to_file "External link")(outputfile, inputfile, bigfile=False)

### Remarks

This function extracts the signed data from the signed-data CMS object without making any attempt to verify it.
Any existing file with the same name as the specified output will be overwritten without further warning.

This function automatically checks for and reads "naked" SignedData files
as per PKCS#7 version 1.6 [[PKCS7-EXT](#PKCS7-EXT)] as well as the default SignedData objects 
properly encapsulated in an outerContentInfo as per the S/MIME standard.

### Example

This example reads the content from the signed CMS object created in the example for [CMS_MakeSigData](#CMS_MakeSigData) above. 
The output is written directly to a file and should contain the 28 bytes "This is some sample content."

```

Dim nRet As Long
Dim strFileIn As String
Dim strFileOut As String

strFileIn = "BasicSignByAlice.bin"
strFileOut = "BasicSignByAlice.dat"
nRet = CMS_ReadSigData(strFileOut, strFileIn, 0)
Debug.Print "CMS_ReadSigData returns " & nRet

```

The function should return 28 indicating the number of bytes written to the output file.

### See Also

[CMS_ReadSigDataToString](#CMS_ReadSigDataToString)
[CMS_GetSigDataDigest](#CMS_GetSigDataDigest)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CMS_ReadSigDataToBytes"></a>CMS_ReadSigDataToBytes
---------------------------------------------------------

Reads the content from a CMS signed-data object file directly into a byte array.

### VBA/VB6 Syntax

`Public Declare Function CMS_ReadSigDataToBytes Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByVal strFileIn As String, ByVal nOptions As Long) As Long`

`nRet = CMS_ReadSigDataToBytes(lpOutput(0), nOutBytes, strFileIn, nOptions) As Long`

### C/C++ Syntax

`long __stdcall CMS_ReadSigDataToBytes(unsigned char *lpOutput, long nOutBytes, const char *szFileIn, long nOptions);`

### Parameters

*lpOutput*
:   [out] buffer to receive the output.

*nOutBytes*
:   [in] length of the output buffer.

*szFileIn*
:   [in] with name of signed-data CMS object file (binary or base64-encoded)
	or the data as a [base64 or PEM string](#cmsbase64pem).

*nOptions*
:   [in] option flags:   

`PKI_DEFAULT` (0) for default options

### Returns (VBA/C)

If successful, the return value is a positive number indicating the number of bytes in the content;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cmsReadSigDataToBytes`](#VB_cmsReadSigDataToBytes) (szFileIn As String, Optional nOptions As Long = 0) As Byte()

### .NET Equivalent

[Cms.ReadSigDataToBytes Method](#M_Cms_ReadSigDataToBytes)  

### C++ (STL) Equivalent

static bvec_t [dipki::Cms::ReadSigDataToBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a195dd3ffebf14da82afbcb38c0d3ee70 "External link") (const std::string &inputFile)

### Python Equivalent

static [Cms.read_sigdata_to_bytes](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.read_sigdata_to_bytes "External link")(inputfile)

### Remarks

This function extracts the signed content from the signed-data CMS object without making any attempt to verify it.
Call the function with a NULL *abOutput* array or zero *nOutBytes* parameter to find out the required length of
the output buffer.
The buffer must be large enough to receive the entire output or a `SHORT_BUF_ERROR` error will result.

Use this function if the content contains non-ASCII characters such as UTF-8 encoded.

### Example (VBA core function)

This example reads the content from the signed CMS object created in the example for 
[`CMS_MakeSigDataFromBytes`](#CMS_MakeSigDataFromBytes).

```

Dim nRet As Long
Dim strSigDataFile As String
Dim abData() As Byte
Dim nBytes As Long

strSigDataFile = "basicsignedbyalice_utf8.p7m"
Debug.Print "Reading signed-data file '" & strSigDataFile & "'"
' How long is the content to be read?
nBytes = CMS_ReadSigDataToBytes(ByVal 0&, 0, strSigDataFile, 0)
Debug.Print "CMS_ReadSigDataToBytes returns " & nBytes
If nBytes <= 0 Then
	Exit Function
End If
' Dimension byte array to receive data
ReDim abData(nBytes - 1)
nBytes = CMS_ReadSigDataToBytes(abData(0), nBytes, strSigDataFile, 0)
' Display extracted content in hex
Debug.Print "HEX(data)=" & cnvHexStrFromBytes(abData) & " (" & UBound(abData) + 1 & " bytes)"

```

This should result in the output:

```

Reading signed-data file 'basicsignedbyalice_utf8.p7m'
CMS_ReadSigDataToBytes returns 38
HEX(data)=3C646F633E3C6E616D6520633D276573273EC38DC3B169676F3C2F6E616D653E3C2F646F633E (38 bytes)

```

### Example (VBA wrapper function)

```

Dim lpData() As Byte
Dim strData As String

' Read UTF-8 encoded data from signed-data CMS object
lpData = cmsReadSigDataToBytes("basicsignedbyalice_utf8.p7m")
Debug.Assert cnvBytesLen(lpData) > 0
Debug.Print "HEX(CONTENT)=" & cnvHexStrFromBytes(lpData)
' Convert from UTF-8-encoded bytes to VB Unicode string
strData = cnvLatin1FromUTF8Bytes(lpData)
Debug.Print "CONTENT='" & strData & "'"
```

### See Also

[CMS_ReadSigData](#CMS_ReadSigData)
[CMS_ReadSigDataToString](#CMS_ReadSigDataToString)
[CMS_GetSigDataDigest](#CMS_GetSigDataDigest)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CMS_ReadSigDataToString"></a>CMS_ReadSigDataToString
-----------------------------------------------------------

Reads the content from a CMS signed-data object file directly into a string.

### VBA/VB6 Syntax

`Public Declare Function CMS_ReadSigDataToString Lib "diCrPKI.dll" 
    (ByVal strDataOut As String, ByVal nDataLen As Long, 
    ByVal strFileIn As String, ByVal nOptions As Long) As Long`

`nRet = CMS_ReadSigDataToString(strDataOut, nDataLen, strFileIn, 
    nOptions) As Long`

### C/C++ Syntax

`long __stdcall CMS_ReadSigDataToString(char *szOutput, long nOutChars, const char *szFileIn, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive the output.

*nOutChars*
:   [in] specifying the length of the output string.

*szFileIn*
:   [in] with name of signed-data CMS object file (binary or base64-encoded)
	or the data as a [base64 or PEM string](#cmsbase64pem).

*nOptions*
:   [in] option flags:   

`PKI_DEFAULT` (0) for default options

### Returns (VBA/C)

If successful, the return value is a positive number indicating the number of bytes in the content;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cmsReadSigDataToString`](#VB_cmsReadSigDataToString) (szFileIn As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Cms.ReadSigDataToString Method](#M_Cms_ReadSigDataToString)  

### Python Equivalent

static [Cms.read_sigdata_to_string](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.read_sigdata_to_string "External link")(inputfile)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

This function extracts the signed data from the signed-data CMS object without making any attempt to verify it.

The buffer must be large enough to receive the entire output or a `SHORT_BUF_ERROR` error will result.

Use this only when the signed content is known to be plain ASCII text, otherwise use [CMS_ReadSigDataToBytes](#CMS_ReadSigDataToBytes).

### Example (VBA core function)

This example reads the content from the signed CMS object from example 4.2 in 
[[SMIME-EX]](#SMIME-EX).

```

Dim nRet As Long
Dim strFileIn As String
Dim strData As String
Dim nDataLen As Long
strFileIn = "4.2.bin"
' How long is the content to be read?
nDataLen = CMS_ReadSigDataToString("", 0, strFileIn, 0)
If nDataLen <= 0 Then
    Exit Function
End If
' Pre-dimension string to receive data
strData = String(nDataLen, " ")
nRet = CMS_ReadSigDataToString(strData, nDataLen, strFileIn, 0)
Debug.Print "CMS_ReadSigDataToString returns " & nRet
Debug.Print "Data is [" & strData & "]"

```

This should result in the output:

```

CMS_ReadSigDataToString returns 28
Data is [This is some sample content.]

```

### Example (VBA wrapper function)

```

Dim strHexDigest As String
Dim strData As String
Const strCMSFile As String = "4.2.bin"

' Extract the digest value
strHexDigest = cmsGetSigDataDigest(strCMSFile, "")
Debug.Print "extracted digest=[" & strHexDigest & "]"
' Extract content from signed-data file
strData = cmsReadSigDataToString(strCMSFile)
Debug.Print "content='" & strData & "'"
' Compute digest value over the content
Debug.Print "computed digest =[" & hashHexFromBytes(StrConv(strData, vbFromUnicode), PKI_HASH_SHA1) & "]"

```

### See Also

[CMS_ReadSigData](#CMS_ReadSigData)
[CMS_ReadSigDataToBytes](#CMS_ReadSigDataToBytes)
[CMS_GetSigDataDigest](#CMS_GetSigDataDigest)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CMS_VerifySigData"></a>CMS_VerifySigData
-----------------------------------------------

Verifies the signature and content of a signed-data CMS object file.

### VBA/VB6 Syntax

`Public Declare Function CMS_VerifySigData Lib "diCrPKI.dll" 
    (ByVal strFileIn As String, ByVal strCertFile As String, 
    ByVal strHexDigest As String, ByVal nOptions As Long) As Long`

`nRet = CMS_VerifySigData(strFileIn, strCertFile, strHexDigest, nOptions) As Long`

### C/C++ Syntax

`long __stdcall CMS_VerifySigData(const char *szFileIn, const char *szCertFile, const char *szHexDigest, long nOptions);`

### Parameters

*szFileIn*
:   [in] specifying the name of the signed-data CMS object file (binary or base64-encoded)
	or the data as a [base64 or PEM string](#cmsbase64pem).

*szCertFile*
:   [in] (optional) specifying an X.509 certificate file
to be used to identify the signer. Specify an empty string `""` to use the certificate(s)
in the input file.

*szHexDigest*
:   [in] (optional) specifying a message digest 
	encoded in hexadecimal format.
	Use this to verify a "detached-signature" input file. 
	Specify an empty string `""` to verify the eContent data in the SignedData file.

*nOptions*
:   [in] option flags:   

`PKI_DEFAULT` (0) for default options.  

`PKI_CMS_BIGFILE` to speed up the processing of large files (binary input only).

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cmsVerifySigData`](#VB_cmsVerifySigData) (szFileIn As String, Optional szCertFile As String = "", Optional szHexDigest As String = "", Optional nOptions As Long = 0) As Long

### .NET Equivalent

[Cms.VerifySigData Method](#M_Cms_VerifySigData)  

### C++ (STL) Equivalent

static bool [dipki::Cms::VerifySigData](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a716d8daac452731ba32ebf01616f02d9 "External link") (const std::string &inputFile, const std::string &certFile="", const std::string &hexDigest="", bool bigFile=false)

### Python Equivalent

static [Cms.verify_sigdata](https://cryptosys.net/pki/pydocpki/class-stubs/Cms.html#cryptosyspki.Cms.verify_sigdata "External link")(sigdatafile, certfile="", hexdigest="", bigfile=False)

### Remarks

This function verifies that the content was indeed signed by the purported signer. Note that it returns *zero*
to indicate success, not true. 
If a certificate is specified in *szCertFile* then the public key from that certificate will be used
and a matching signerInfo will be searched for in the SignedData file. Otherwise the first matching pair of
certificate and signerInfo found in the SignedData file will be used.

If the signed content (eContent) is included in the SignedData object (this is the usual case), then specify an empty string (`""`)
for *szHexDigest*. For a "detached-signature" file where the signed content
has been passed to the user by other means, 
compute a separate message digest of the data and pass it to the function in the 
*szHexDigest* parameter.

This function handles SignedData objects both with and without signedAttributes.

*[New in v12.4]*
If an ESS Signing Certificate attribute is found, then the purported signing certificate will be checked against the value of this attribute 
as per ESS [[RFC5035](#RFC5035)] and CAdES [[CADES](#CADES)].
It is a `SIGNATURE_ERROR` (22) if these do not match.

*[New in v12.4]*
If an Algorithm Protection Attribute is found, then further verification checks will be made to prevent algorithm substitution attacks as per [[RFC6211](#RFC6211)].
It is a `SIGNATURE_ERROR` (22) if these checks fail.

### Example

```

Dim nRet As Long
Dim strInputFile As String
strInputFile = "BasicSignByAlice.bin"
nRet = CMS_VerifySigData(strInputFile, "", "", 0)
Debug.Print "CMS_VerifySigData returns " & nRet & " (expecting 0)"

```

### See Also

[CMS_GetSigDataDigest](#CMS_GetSigDataDigest)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_B64Filter"></a>CNV_B64Filter
---------------------------------------

Removes non-base64 characters from a string.

### VBA/VB6 Syntax

`Public Declare Function CNV_B64Filter Lib "diCrPKI.dll" 
    (ByVal strOutput As String, ByVal strInput As String, ByVal nStrLen As Long) As Long`

`nRet = CNV_B64Filter(strOutput, strInput, nStrLen)`

### C/C++ Syntax

`long __stdcall CNV_B64Filter(char *szOutput, const char *szInput, long nStrLen);`

### Parameters

*szOutput*
:   [out] to receive filtered characters.

*szInput*
:   [in] to be filtered.

*nStrLen*
:   [in] specifying the length of the input string.

### Returns (VBA/C)

If successful, the return value is the number of characters in the filtered string; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cnvB64Filter`](#VB_cnvB64Filter) (szB64 As String) As String

### .NET Equivalent

[Cnv.Base64Filter Method](#M_Cnv_Base64Filter)  

### Remarks

Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length of the output string.
ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

Assumes that the output string is at least as long as the input string.

### Example (VBA core function)

Wrapper function to return a filtered string directly:

```

Public Function cnvB64Filter(strB64 As String) As String
    Dim strFiltered As String
    Dim nDataLen As Long
    
    strFiltered = String(Len(strB64), " ")
    nDataLen = CNV_B64Filter(strFiltered, strB64, Len(strB64))
    strFiltered = Left$(strFiltered, nDataLen)
    cnvB64Filter = strFiltered
End Function

```

### See Also

[CNV_B64StrFromBytes](#CNV_B64StrFromBytes)
[CNV_BytesFromB64Str](#CNV_BytesFromB64Str)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_B64StrFromBytes"></a>CNV_B64StrFromBytes
---------------------------------------------------

Encodes an array of bytes into a base64-encoded string.

### VBA/VB6 Syntax

`Public Declare Function CNV_B64StrFromBytes Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByRef lpInput As Byte, ByVal nInputLen As Long) As Long`

`nRet = CNV_B64StrFromBytes(strOutput, nOutChars, lpInput(0), nInputLen)`

### C/C++ Syntax

`long __stdcall CNV_B64StrFromBytes(char *szOutput, long nOutChars, const unsigned char *lpInput, long nInputLen);`

### Parameters

*szOutput*
:   [out] to receive encoded data.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*lpInput*
:   [in] array of binary data to be encoded.

*nInputLen*
:   [in] number of bytes to be encoded.

### Returns (VBA/C)

If successful, the return value is the number of characters in the encoded string; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cnvB64StrFromBytes`](#VB_cnvB64StrFromBytes) (lpData() As Byte) As String  
Public Function [`cnvB64StrFromHexStr`](#VB_cnvB64StrFromHexStr) (szHex As String) As String  
Public Function [`cnvB64StrFromString`](#VB_cnvB64StrFromString) (szData As String) As String  
Public Function [`cnvToBase64`](#VB_cnvToBase64) (lpData() As Byte) As String

### .NET Equivalent

[Cnv.ToBase64 Method](#M_Cnv_ToBase64_Byte) (Byte[])  

[Cnv.ToBase64 Method](#M_Cnv_ToBase64_String) (String)  

### C++ (STL) Equivalent

static std::string [dipki::Cnv::ToBase64](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a53fa6ab77bbb5623e134f72199a407d6 "External link") (const bvec_t &bv)  

static std::string [dipki::Cnv::ToBase64](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a8e32a430afe218683b5f63f64b08e641 "External link") (const std::string &s)

### Python Equivalent

static [Cnv.tobase64](https://cryptosys.net/pki/pydocpki/class-stubs/Cnv.html#cryptosyspki.Cnv.tobase64 "External link")(data)

### Remarks

Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length of the output string.
ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

This uses the base64 encoding scheme from [[RFC4648](#RFC4648)].
Pass a zero value of *nOutChars* to find the required maximum possible number of characters in the output string.
The final result may be smaller.
C/C++ programmers should add one to the returned length value when allocating memory for *szOutput*.

### Example (VBA core function)

The following wrapper function returns a base64-encoded string directly. Note the trap for a runtime error if the input byte array is empty.

```

Public Function cnvB64StrFromBytes(abData() As Byte) As String
' Returns base64 string encoding of bytes in abData or empty string on error
    Dim strB64 As String
    Dim nB64Len As Long
    Dim nDataLen As Long
    
    On Error GoTo CatchEmptyData
    nDataLen = UBound(abData) - LBound(abData) + 1
    nB64Len = CNV_B64StrFromBytes(vbNullString, 0, abData(0), nDataLen)
    If nB64Len <= 0 Then
        Exit Function
    End If
    strB64 = String$(nB64Len, " ")
    nB64Len = CNV_B64StrFromBytes(strB64, nB64Len, abData(0), nDataLen)
    If nB64Len <= 0 Then
        Exit Function
    End If
    cnvB64StrFromBytes = Left$(strB64, nB64Len)
    
CatchEmptyData:

End Function

```

### See Also

[CNV_BytesFromB64Str](#CNV_BytesFromB64Str)
[CNV_B64Filter](#CNV_B64Filter)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_Base58FromBytes"></a>CNV_Base58FromBytes
---------------------------------------------------

Encodes an array of bytes into a base58-encoded string.

### VBA/VB6 Syntax

`Public Declare Function CNV_Base58FromBytes Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByRef lpInput As Byte, ByVal nInputLen As Long) As Long`

`nRet = CNV_Base58FromBytes(strOutput, nOutChars, lpInput(0), nInputLen)`

### C/C++ Syntax

`long __stdcall CNV_Base58FromBytes(char *szOutput, long nOutChars, const unsigned char *lpInput, long nInputLen);`

### Parameters

*szOutput*
:   [out] to receive encoded data.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*lpInput*
:   [in] array of binary data to be encoded.

*nInputLen*
:   [in] number of bytes to be encoded.

### Returns (VBA/C)

If successful, the return value is the number of characters in the encoded string; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cnvBase58FromBytes`](#VB_cnvBase58FromBytes) (lpInput() As Byte) As String

### .NET Equivalent

[Cnv.ToBase58 Method](#M_Cnv_ToBase58)  

### C++ (STL) Equivalent

static std::string [dipki::Cnv::ToBase58](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#af09afd9cc0eacd54cbc66b9ea0ff1c43 "External link") (const bvec_t &bv)

### Python Equivalent

static [Cnv.tobase58](https://cryptosys.net/pki/pydocpki/class-stubs/Cnv.html#cryptosyspki.Cnv.tobase58 "External link")(data)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

This uses the "Bitcoin" scheme of base58 encoding where the leading character '1' is reserved for representing an entire leading zero byte
[[BTC-B58](#BTC-B58)].

### Example (VBA core function)

```

Dim strBase58 As String
Dim abData() As Byte
Dim nBytes As Long
Dim nChars As Long

' Create a byte array for testing
abData = cnvBytesFromHexStr("00010966776006953D5567439E5E39F86A0D273BEED61967F6")
nBytes = UBound(abData) + 1
Debug.Print "INPUT: " & cnvHexStrFromBytes(abData)

' Encode bytes as base58 string
' Find length of output string
nChars = CNV_Base58FromBytes("", 0, abData(0), nBytes)
If nChars < 0 Then Exit Sub ' ERROR
' Dimension string to receive output
strBase58 = String(nChars, " ")
' Create output string
nChars = CNV_Base58FromBytes(strBase58, nChars, abData(0), nBytes)

Debug.Print "OUTPUT: " & strBase58

```

```

INPUT: 00010966776006953D5567439E5E39F86A0D273BEED61967F6
OUTPUT: 16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM

```

### Example (VBA wrapper function)

```

Dim lpData() As Byte
Dim strBase58 As String

lpData = cnvBytesFromHexStr("00010966776006953D5567439E5E39F86A0D273BEED61967F6")
strBase58 = cnvBase58FromBytes(lpData)
Debug.Print strBase58
' Decode base58 string to byte array
lpData = cnvBase58ToBytes(strBase58)
Debug.Print cnvHexStrFromBytes(lpData)
strBase58 = "DiManagement"
Debug.Print "INPUT: " & strBase58
lpData = cnvBase58ToBytes(strBase58)
Debug.Print cnvHexStrFromBytes(lpData)
   
```

### See Also

[CNV_Base58ToBytes](#CNV_Base58ToBytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_Base58ToBytes"></a>CNV_Base58ToBytes
-----------------------------------------------

Decodes a base58-encoded string into an array of bytes.

### VBA/VB6 Syntax

`Public Declare Function CNV_Base58ToBytes Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByVal strInput As String) As Long`

`nRet = CNV_Base58ToBytes(lpOutput(0), nOutBytes, strInput)`

### C/C++ Syntax

`long __stdcall CNV_Base58ToBytes(unsigned char *lpOutput, long nOutBytes, const char *szInput);`

### Parameters

*lpOutput*
:   [out] array suitably dimensioned to receive decoded output.

*nOutBytes*
:   [in] specifying the maximum number of bytes to be received.

*szInput*
:   [in] base58 data to be decoded.

### Returns (VBA/C)

If successful, the return value is the number of bytes in the decoded array; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cnvBase58ToBytes`](#VB_cnvBase58ToBytes) (szInput As String) As Byte()

### .NET Equivalent

[Cnv.FromBase58 Method](#M_Cnv_FromBase58)  

### C++ (STL) Equivalent

static bvec_t [dipki::Cnv::FromBase58](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a1eb3f31614c1aa5286af0c7823f7f8db "External link") (const std::string &s)

### Python Equivalent

static [Cnv.frombase58](https://cryptosys.net/pki/pydocpki/class-stubs/Cnv.html#cryptosyspki.Cnv.frombase58 "External link")(s)

### Remarks

This uses the "Bitcoin" scheme of base58 encoding where the leading character '1' is reserved for representing an entire leading zero byte
[[BTC-B58](#BTC-B58)].
Pass a zero value for *nOutBytes* to find the required number of bytes in the output array. 

### Example (VBA core function)

```

Dim strBase58 As String
Dim abData() As Byte
Dim nBytes As Long

' Decode base58 string to byte array
strBase58 = "16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM"
Debug.Print "INPUT: " & strBase58
nBytes = CNV_Base58ToBytes(0, 0, strBase58)
If nBytes < 0 Then Exit Sub ' ERROR
ReDim abData(nBytes - 1)
nBytes = CNV_Base58ToBytes(abData(0), nBytes, strBase58)
' Display byte array in hex
Debug.Print "OUTPUT=" & cnvHexStrFromBytes(abData)

' Again (plug!)
strBase58 = "DiManagement"
Debug.Print "INPUT: " & strBase58
nBytes = CNV_Base58ToBytes(0, 0, strBase58)
If nBytes < 0 Then Exit Sub ' ERROR
ReDim abData(nBytes - 1)
nBytes = CNV_Base58ToBytes(abData(0), nBytes, strBase58)
' Display byte array in hex
Debug.Print "OUTPUT=" & cnvHexStrFromBytes(abData)

```

```

INPUT: 16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
OUTPUT=00010966776006953D5567439E5E39F86A0D273BEED61967F6
INPUT: DiManagement
OUTPUT=11385B5358CD2B71E9

```

### Example (VBA wrapper function)

```

Dim lpData() As Byte
Dim strBase58 As String

lpData = cnvBytesFromHexStr("00010966776006953D5567439E5E39F86A0D273BEED61967F6")
strBase58 = cnvBase58FromBytes(lpData)
Debug.Print strBase58
' Decode base58 string to byte array
lpData = cnvBase58ToBytes(strBase58)
Debug.Print cnvHexStrFromBytes(lpData)
strBase58 = "DiManagement"
Debug.Print "INPUT: " & strBase58
lpData = cnvBase58ToBytes(strBase58)
Debug.Print cnvHexStrFromBytes(lpData)
   
```

### See Also

[CNV_Base58FromBytes](#CNV_Base58FromBytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_ByteEncoding"></a>CNV_ByteEncoding
---------------------------------------------

Converts encoding of byte array between UTF-8 and Latin-1.

### VBA/VB6 Syntax

`Public Declare Function CNV_ByteEncoding Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByRef lpInput As Byte, ByVal nBytes As Long, ByVal nOptions As Long) As Long`

`nLen = CNV_ByteEncoding(lpOutput(0), nOutBytes, lpInput(0), nBytes, nOptions) ' Note the "(0)" after the byte array parameters`

### C/C++ Syntax

`long __stdcall CNV_ByteEncoding(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpInput, long nBytes, long nOptions);`

### Parameters

*lpOutput*
:   [out] array suitably dimensioned to receive output..

*nOutBytes*
:   [in] specifying the maximum number of bytes to be received.

*lpInput*
:   [in] array containing input data.

*nBytes*
:   [in] number of bytes in input array.

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_CNV_UTF8_FROM_LATIN1` (1) to convert from UTF-8 encoding to Latin-1  

`PKI_CNV_LATIN1_FROM_UTF8` (2) to convert from Latin-1 encoding to UTF-8

### Returns (VBA/C)

If successful, the return value is a positive number indicating the 
number of bytes in the output array, or number of bytes required if *nOutBytes* is set to zero; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cnvByteEncoding`](#VB_cnvByteEncoding) (lpInput() As Byte, nOptions As Long) As Byte()

### .NET Equivalent

[Cnv.ByteEncoding Method](#M_Cnv_ByteEncoding)  

### Remarks

Converting UTF-8 from Latin-1 assumes the input is from the 8-bit Latin-1 character set
and so will *always* produce output that is valid UTF-8.
However, for Latin-1 from UTF-8, the input *must* contain a
valid sequence of UTF-8-encoded bytes and this must be convertible
to a single-byte character set, or an error will be returned.

### Example (VBA core function)

```

Dim abLatin1() As Byte
Dim abUTF8() As Byte
Dim nLatBytes As Long
Dim nUtfBytes As Long
' Set up a byte array with the following 4 characters encoded in Latin-1
'  U+0061 LATIN SMALL LETTER A
'  U+00E9 LATIN SMALL LETTER E WITH ACUTE
'  U+00F1 LATIN SMALL LETTER N WITH TILDE
'  U+0062 LATIN SMALL LETTER B
nLatBytes = 4
ReDim abLatin1(nLatBytes - 1)  ' NB required size minus 1
abLatin1(0) = Asc("a")
abLatin1(1) = &HE9
abLatin1(2) = &HF1
abLatin1(3) = Asc("b")
' Display in hex format
Debug.Print "Latin-1=" & cnvHexStrFromBytes(abLatin1) & " (" & nLatBytes & " bytes)"
' Convert encoding to UTF-8
' First find new length and pre-dimension array
nUtfBytes = CNV_ByteEncoding(0, 0, abLatin1(0), nLatBytes, PKI_CNV_UTF8_FROM_LATIN1)
If nUtfBytes <= 0 Then Exit Sub 'ERROR
ReDim abUTF8(nUtfBytes - 1)
nUtfBytes = CNV_ByteEncoding(abUTF8(0), nUtfBytes, abLatin1(0), nLatBytes, PKI_CNV_UTF8_FROM_LATIN1)
' Display in hex format
Debug.Print "UTF-8  =" & cnvHexStrFromBytes(abUTF8) & " (" & nUtfBytes & " bytes)"

```

This should result in output as follows:

```

Latin-1=61E9F162 (4 bytes)
UTF-8  =61C3A9C3B162 (6 bytes)

```

### Example (VBA wrapper function)

```

Dim lpLatin1() As Byte
Dim lpUTF8() As Byte
' Set up a byte array with the following 4 characters encoded in Latin-1
'  U+0061 LATIN SMALL LETTER A
'  U+00E9 LATIN SMALL LETTER E WITH ACUTE
'  U+00F1 LATIN SMALL LETTER N WITH TILDE
'  U+0062 LATIN SMALL LETTER B
lpLatin1 = cnvBytesFromHexStr("61E9F162")
Debug.Print "Latin-1=" & cnvHexStrFromBytes(lpLatin1) & " (" & cnvBytesLen(lpLatin1) & " bytes)"
lpUTF8 = cnvByteEncoding(lpLatin1, PKI_CNV_UTF8_FROM_LATIN1)
Debug.Print "UTF-8  =" & cnvHexStrFromBytes(lpUTF8) & " (" & cnvBytesLen(lpUTF8) & " bytes)"
' And back again the other way...
lpLatin1 = cnvByteEncoding(lpUTF8, PKI_CNV_LATIN1_FROM_UTF8)
Debug.Print "Latin-1=" & cnvHexStrFromBytes(lpLatin1) & " (" & cnvBytesLen(lpLatin1) & " bytes)"
```

### See Also

[CNV_UTF8BytesFromLatin1](#CNV_UTF8BytesFromLatin1)
[CNV_Latin1FromUTF8Bytes](#CNV_Latin1FromUTF8Bytes)
[CNV_CheckUTF8Bytes](#CNV_CheckUTF8Bytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_BytesFromB64Str"></a>CNV_BytesFromB64Str
---------------------------------------------------

Decodes a base64-encoded string into an array of Bytes.

### VBA/VB6 Syntax

`Public Declare Function CNV_BytesFromB64Str Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByVal strInput As String) As Long`

`nLen = CNV_BytesFromB64Str(lpOutput(0), nOutBytes, strInput)`

### C/C++ Syntax

`long __stdcall CNV_BytesFromB64Str(unsigned char *lpOutput, long nOutBytes, const char *szInput);`

### Parameters

*lpOutput*
:   [out] array suitably dimensioned to receive output.

*nOutBytes*
:   [in] specifying the maximum number of bytes to be received.

*szInput*
:   [in] base64 data to be decoded.

### Returns (VBA/C)

If successful, the return value is the number of bytes in the decoded array; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cnvBytesFromB64Str`](#VB_cnvBytesFromB64Str) (szB64 As String) As Byte()  
Public Function [`cnvFromBase64`](#VB_cnvFromBase64) (strBase64 As String) As Byte()

### .NET Equivalent

[Cnv.FromBase64 Method](#M_Cnv_FromBase64) 

### C++ (STL) Equivalent

static bvec_t [dipki::Cnv::FromBase64](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#af74aa67af858aea47407c4e55fd23e97 "External link") (const std::string &s)

### Python Equivalent

static [Cnv.frombase64](https://cryptosys.net/pki/pydocpki/class-stubs/Cnv.html#cryptosyspki.Cnv.frombase64 "External link")(s)

### Remarks

This uses the base64 encoding scheme from [[RFC4648](#RFC4648)].
Pass a zero value for *nOutBytes* to find the required maximum possible number of bytes in the output array.
The final array may be shorter. 

**@warning** *[Changed in v11.1]* This function now returns an error if it finds an illegal character in the input string
	(previously any non-base64 character was just ignored).
	Whitespace characters (space, TAB, LF, CR, VT, FF) are still allowed and ignored 
	but any other non-base64 characters will cause an error.

### Example (VBA core function)

The following wrapper function will return the decoded bytes directly, with a default return value that won't cause a run-time error in the calling code.

```

Public Function cnvBytesFromB64Str(strB64 As String) As Byte()
' Returns byte array decoded from a base64 string
    Dim abData() As Byte
    Dim nDataLen As Long
    
    ' Set default return value that won't cause a run-time error
    cnvBytesFromB64Str = vbNullString
    nDataLen = CNV_BytesFromB64Str(0, 0, strB64)
    If nDataLen <= 0 Then
        Exit Function
    End If
    ReDim abData(nDataLen - 1)
    nDataLen = CNV_BytesFromB64Str(abData(0), nDataLen, strB64)
    If nDataLen <= 0 Then
        Exit Function
    End If
    ReDim Preserve abData(nDataLen - 1)
    cnvBytesFromB64Str = abData
End Function

```

#### New stricter behaviour in [v11.1]

Old behaviour in the VBA immediate window:

```

? cnvHexStrFromBytes(cnvBytesFromB64Str("---BEGIN---/ty6mHZUMhA="))
04418837FB72EA61D950C840

```

Result is 12 bytes long.
The non-base64 character '-' is ignored. The valid but probably unintended characters "BEGIN" are decoded.

New behaviour:

```

? cnvHexStrFromBytes(cnvBytesFromB64Str("---BEGIN---/ty6mHZUMhA="))

? PKI_ErrorCode()
 8 

```

Result is 0 bytes long. Error code 8 (INVALID_DATA_ERROR) is set.

### See Also

[CNV_B64StrFromBytes](#CNV_B64StrFromBytes)
[CNV_B64Filter](#CNV_B64Filter)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_BytesFromHexStr"></a>CNV_BytesFromHexStr
---------------------------------------------------

Decodes a hexadecimal-encoded string into an array of Bytes.

### VBA/VB6 Syntax

`Public Declare Function CNV_BytesFromHexStr Lib "diCrPKI.dll" 
    (ByRef lpData As Byte, ByVal nDataLen As Long, ByVal strHex As String) As Long`

`nLen = CNV_BytesFromHexStr(lpData(0), nDataLen, strHex)`

### C/C++ Syntax

`long __stdcall CNV_BytesFromHexStr(unsigned char *lpOutput, long nOutBytes, const char *szInput);`

### Parameters

*lpOutput*
:   [out] array suitably dimensioned to receive output.

*nOutBytes*
:   [in] specifying the length of the byte array.

*szInput*
:   [in] of hexadecimal data to be decoded.

### Returns (VBA/C)

If successful, the return value is the number of bytes in the decoded array; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cnvBytesFromHexStr`](#VB_cnvBytesFromHexStr) (szHex As String) As Byte()  
Public Function [`cnvFromHex`](#VB_cnvFromHex) (strHex As String) As Byte()  
Public Function [`cnvStringFromHexStr`](#VB_cnvStringFromHexStr) (ByVal szHex As String) As String

### .NET Equivalent

[Cnv.FromHex Method](#M_Cnv_FromHex)  

### C++ (STL) Equivalent

static bvec_t [dipki::Cnv::FromHex](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#ae5758db60d6e736aa7f02d9897d88d25 "External link") (const std::string &s)

### Python Equivalent

static [Cnv.fromhex](https://cryptosys.net/pki/pydocpki/class-stubs/Cnv.html#cryptosyspki.Cnv.fromhex "External link")(s)

### Remarks

Call the function with a null *lpOutput* array or zero *nOutBytes* to find the required length.

**@warning** *[Changed in v11.1]* This function now returns an error if it finds an illegal character in the input string
	(previously any non-hex character was just ignored).
	Whitespace characters and ASCII punctuation characters are still allowed and ignored (so `"DE:AD:BE:EF"` is OK)
	but characters like those in the range `[G-Zg-z]` that are obviously non-hex will cause an error.

### Example (VBA core function)

The following wrapper function will return the decoded bytes directly, with a default return value that won't cause a run-time error in the calling code.

```

Public Function cnvBytesFromHexStr(strHex As String) As Byte()
' Returns byte array decoded from a hex string
    Dim abData() As Byte
    Dim nDataLen As Long
    
    ' Set default return value that won't cause a run-time error
    cnvBytesFromHexStr = vbNullString
    nDataLen = CNV_BytesFromHexStr(0, 0, strHex)
    If nDataLen <= 0 Then
        Exit Function
    End If
    ReDim abData(nDataLen - 1)
    nDataLen = CNV_BytesFromHexStr(abData(0), nDataLen, strHex)
    If nDataLen <= 0 Then
        Exit Function
    End If
    ReDim Preserve abData(nDataLen - 1)
    cnvBytesFromHexStr = abData
End Function

```

#### New stricter behaviour in [v11.1]

Old behaviour in the VBA immediate window:

```

? cnvHexStrFromBytes(cnvBytesFromHexStr("DEAGBEEF"))
DEABEE

```

Result is 3 bytes long. Invalid letter 'G' is silently ignored. 
Then the final odd letter 'F' is stripped.

New behaviour:

```

? cnvHexStrFromBytes(cnvBytesFromHexStr("DEAGBEEF"))

? PKI_ErrorCode()
8 

```

Result is 0 bytes long. Error code 8 (INVALID_DATA_ERROR) is set.

### See Also

[CNV_HexStrFromBytes](#CNV_HexStrFromBytes)
[CNV_HexFilter](#CNV_HexFilter)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_CheckUTF8"></a>CNV_CheckUTF8
---------------------------------------

Checks if a string only contains valid UTF-8 characters.
  

@deprecated	 
Use [`CNV_CheckUTF8Bytes()`](#CNV_CheckUTF8Bytes) instead.

### VBA/VB6 Syntax

`Public Declare Function CNV_CheckUTF8 Lib "diCrPKI.dll" 
    (ByVal strInput As String) As Long`

`nLen = CNV_CheckUTF8(strInput)`

### C/C++ Syntax

`long __stdcall CNV_CheckUTF8(const char *szInput);`

### Parameters

*szInput*
:   [in] to be checked.

### Returns (VBA/C)

Returns zero if the string is invalid UTF-8, 
or a positive number if the string is valid UTF-8.

### .NET Equivalent

Not applicable in .NET.

### C++ (STL) Equivalent

static int [dipki::Cnv::CheckUTF8](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a03053e41be4471efaacc4c178671e92d "External link") (const bvec_t &bv)

### Remarks

### Example

### See Also

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_CheckUTF8Bytes"></a>CNV_CheckUTF8Bytes
-------------------------------------------------

Checks if a byte array contains valid UTF-8 characters.

### VBA/VB6 Syntax

`Public Declare Function CNV_CheckUTF8Bytes Lib "diCrPKI.dll" (ByRef lpInput As Byte, ByVal nBytes As Long) As Long`

`nLen = CNV_CheckUTF8Bytes(lpInput(0), nBytes)`

### C/C++ Syntax

`long __stdcall CNV_CheckUTF8Bytes(const unsigned char *lpInput, long nBytes);`

### Parameters

*lpInput*
:   [in] array to be checked.

*nBytes*
:   [in] number of bytes in input array.

### Returns (VBA/C)

Returns zero if the byte array contains invalid UTF-8, 
or a positive number if the byte array contains valid UTF-8, 
where the value of the number indicates the nature of the encoded characters (see Remarks below):

### VBA Wrapper Syntax

Public Function [`cnvCheckUTF8Bytes`](#VB_cnvCheckUTF8Bytes) (lpInput() As Byte) As Long

### .NET Equivalent

[Cnv.CheckUTF8 Method](#M_Cnv_CheckUTF8) (Byte[])  

### Python Equivalent

static [Cnv.utf8_check](https://cryptosys.net/pki/pydocpki/class-stubs/Cnv.html#cryptosyspki.Cnv.utf8_check "External link")(data)

### Remarks

Return values:

| Returns | Value | Result |
| --- | --- | --- |
| `PKI_CHRS_NOT_UTF8` | 0 | Not valid UTF-8 |
| `PKI_CHRS_ALL_ASCII` | 1 | Valid UTF-8, all chars are 7-bit ASCII |
| `PKI_CHRS_ANSI8` | 2 | Valid UTF-8, contains at least one multi-byte character equivalent to 8-bit ANSI |
| `PKI_CHRS_MULTIBYTE` | 3 | Valid UTF-8, contains at least one multi-byte character that cannot be represented in a single-byte character set. |

Overlong UTF-8 sequences and illegal surrogates are rejected as invalid. Strings that return 
`PKI_CHRS_ANSI8` (2) can be converted to Latin-1 format using the
[`CNV_Latin1FromUTF8Bytes()`](#CNV_Latin1FromUTF8Bytes) function. Strings that return
`PKI_CHRS_MULTIBYTE` (3) cannot be converted to Latin-1, and strings that return
`PKI_CHRS_ALL_ASCII` (1) are already OK because they only consist of 7-bit ASCII characters.

### Example (VBA core function)

See the example in [`CNV_UTF8BytesFromLatin1`](#CNV_UTF8BytesFromLatin1).

### Example (VBA wrapper function)

```

Dim strData As String
Dim lpDataUTF8() As Byte
strData = "abcóéÍáñ"
Debug.Print "Latin-1 string='" & strData & "'"
Debug.Print " (" & Len(strData) & " characters)"
lpDataUTF8 = cnvUTF8BytesFromLatin1(strData)
Debug.Print "UTF-8=(0x)" & cnvHexStrFromBytes(lpDataUTF8)
Debug.Print " (" & cnvBytesLen(lpDataUTF8) & " bytes)"
Debug.Print "cnvCheckUTF8Bytes returns " & cnvCheckUTF8Bytes(lpDataUTF8) & " (expected 2)"
' And back to a string
Dim strLatin1 As String
strLatin1 = cnvLatin1FromUTF8Bytes(lpDataUTF8)
Debug.Print "Back to string='" & strLatin1 & "'"
```

### See Also

[CNV_CheckUTF8File](#CNV_CheckUTF8File)
[CNV_Latin1FromUTF8Bytes](#CNV_Latin1FromUTF8Bytes)
[CNV_UTF8BytesFromLatin1](#CNV_UTF8BytesFromLatin1)
[CNV_ByteEncoding](#CNV_ByteEncoding)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_CheckUTF8File"></a>CNV_CheckUTF8File
-----------------------------------------------

Checks if a file contains valid UTF-8 characters.

### VBA/VB6 Syntax

`Public Declare Function CNV_CheckUTF8File Lib "diCrPKI.dll" (ByVal strFileName As String) As Long`

`nLen = CNV_CheckUTF8File(strFileName)`

### C/C++ Syntax

`long __stdcall CNV_CheckUTF8File(const char *szFileName);`

### Parameters

*szFileName*
:   [in] containing the name of the file.

### Returns (VBA/C)

Returns zero if the file contains invalid UTF-8, 
or a positive number if the file contains valid UTF-8, 
where the value of the number indicates the nature of the encoded characters:
see [`CNV_CheckUTF8Bytes()`](#CNV_CheckUTF8Bytes) for more details.
If there is an error, like the file is missing or cannot be read, 
then it returns a negative [error code](#errorcodes).

### .NET Equivalent

[Cnv.CheckUTF8File Method](#M_Cnv_CheckUTF8File)  

### C++ (STL) Equivalent

static int [dipki::Cnv::CheckUTF8File](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#acdd517ccb3e1c1c367e2425c1571420a "External link") (const std::string &fileName)

### Python Equivalent

static [Cnv.utf8_check_file](https://cryptosys.net/pki/pydocpki/class-stubs/Cnv.html#cryptosyspki.Cnv.utf8_check_file "External link")(filename)

### Remarks

This is the same as `CNV_CheckUTF8Bytes()` but for a file instead of a byte array.
For more details, see [`CNV_CheckUTF8Bytes()`](#CNV_CheckUTF8Bytes).

### Example

This example examines two XML files containing Spanish characters like é and ó. 
The first is encoded in UTF-8; the second in Latin-1 (ISO-8859-1).

```

Dim strFileName As String
Dim nRet As Long

strFileName = "test-utf8.xml"
nRet = CNV_CheckUTF8File(strFileName)
Debug.Print "CNV_CheckUTF8File(" & strFileName & ") returns " & nRet
strFileName = "test-iso88591.xml"
nRet = CNV_CheckUTF8File(strFileName)
Debug.Print "CNV_CheckUTF8File(" & strFileName & ") returns " & nRet

```

```

CNV_CheckUTF8File(test-utf8.xml) returns 2
CNV_CheckUTF8File(test-iso88591.xml) returns 0

```

### See Also

[`CNV_CheckUTF8Bytes`](#CNV_CheckUTF8Bytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_HexFilter"></a>CNV_HexFilter
---------------------------------------

Removes non-hexadecimal characters from a string.

### VBA/VB6 Syntax

`Public Declare Function CNV_HexFilter Lib "diCrPKI.dll" 
    (ByVal strOutput As String, ByVal strInput As String, ByVal nStrLen As Long) As Long`

`nRet = CNV_HexFilter(strOutput, strInput, nStrLen)`

### C/C++ Syntax

`long __stdcall CNV_HexFilter(char *szOutput, const char *szInput, long nStrLen);`

### Parameters

*szOutput*
:   [out] to receive filtered characters.

*szInput*
:   [in] to be filtered.

*nStrLen*
:   [in] specifying the length of the input string.

### Returns (VBA/C)

If successful, the return value is the number of characters in the filtered string; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cnvHexFilter`](#VB_cnvHexFilter) (szHex As String) As String

### .NET Equivalent

[Cnv.HexFilter Method](#M_Cnv_HexFilter)  

### Remarks

Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length of the output string.
ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

Assumes that the output string is at least as long as the input string.

### Example (VBA core function)

Wrapper function to return a filtered string directly:

```

Public Function cnvHexFilter(strHex As String) As String
    Dim strFiltered As String
    Dim nDataLen As Long
    
    strFiltered = String(Len(strHex), " ")
    nDataLen = CNV_HexFilter(strFiltered, strHex, Len(strHex))
    strFiltered = Left$(strFiltered, nDataLen)
    cnvHexFilter = strFiltered
End Function

```

### See Also

[CNV_HexStrFromBytes](#CNV_HexStrFromBytes)
[CNV_BytesFromHexStr](#CNV_BytesFromHexStr)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_HexStrFromBytes"></a>CNV_HexStrFromBytes
---------------------------------------------------

Encodes an array of bytes into a hexadecimal-encoded string.

### VBA/VB6 Syntax

`Public Declare Function CNV_HexStrFromBytes Lib "diCrPKI.dll" 
    (ByVal strHex As String, ByVal nHexStrLen As Long, 
    ByRef lpData As Byte, ByVal nDataLen As Long) As Long`

`nRet = CNV_HexStrFromBytes(strHex, nHexStrLen, lpData(0), nDataLen)`

### C/C++ Syntax

`long __stdcall CNV_HexStrFromBytes(char *szOutput, long nOutChars, const unsigned char *lpInput, long nInputLen);`

### Parameters

*szOutput*
:   [out] to receive encoded data.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*lpInput*
:   [in] array of binary data to be encoded.

*nInputLen*
:   [in] number of bytes to be encoded.

### Returns (VBA/C)

If successful, the return value is the number of characters in the encoded string; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cnvHexFromBytesMid`](#VB_cnvHexFromBytesMid) (abData() As Byte, nOffset As Long, nBytes As Long) As String  
Public Function [`cnvHexStrFromB64Str`](#VB_cnvHexStrFromB64Str) (szB64 As String) As String  
Public Function [`cnvHexStrFromBytes`](#VB_cnvHexStrFromBytes) (lpData() As Byte) As String  
Public Function [`cnvHexStrFromString`](#VB_cnvHexStrFromString) (szData As String) As String  
Public Function [`cnvToHex`](#VB_cnvToHex) (lpData() As Byte) As String

### .NET Equivalent

[Cnv.ToHex Method](#M_Cnv_ToHex_Byte)  

### C++ (STL) Equivalent

static std::string [dipki::Cnv::ToHex](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a5810eaae94a26966d7b0f3f38d020b53 "External link") (const bvec_t &bv)  

static std::string [dipki::Cnv::ToHex](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#ab8105e17761c59fbd94dada6e4ad553b "External link") (const std::string &s)

### Python Equivalent

static [Cnv.tohex](https://cryptosys.net/pki/pydocpki/class-stubs/Cnv.html#cryptosyspki.Cnv.tohex "External link")(data)

### Remarks

Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length of the output string.
ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The input array may contain bytes of any value. 
If `vbNullString` or an empty string (`""`) is specified for *szHex* or zero for *nHexStrLen*, 
the function will return
the maximum possible size of the encoded string. The final result may be smaller.
C/C++ programmers should add one to the returned length value when allocating memory.

### Example (VBA core function)

The following wrapper function returns an encoded string directly. 
Note that if `abData` is empty then `UBound(abData)` will raise a runtime error. 
So we trap the error and return the default empty string.

```

Public Function cnvHexStrFromBytes(abData() As Byte) As String
' Returns hex string encoding of bytes in abData or empty string on error
    Dim strHex As String
    Dim nHexLen As Long
    Dim nDataLen As Long
    
    On Error GoTo CatchEmptyData
    nDataLen = UBound(abData) - LBound(abData) + 1
    nHexLen = CNV_HexStrFromBytes(vbNullString, 0, abData(0), nDataLen)
    If nHexLen <= 0 Then
        Exit Function
    End If
    strHex = String$(nHexLen, " ")
    nHexLen = CNV_HexStrFromBytes(strHex, nHexLen, abData(0), nDataLen)
    If nHexLen <= 0 Then
        Exit Function
    End If
    cnvHexStrFromBytes = Left$(strHex, nHexLen)
    
CatchEmptyData:

End Function

```

### See Also

[CNV_BytesFromHexStr](#CNV_BytesFromHexStr)
[CNV_HexFilter](#CNV_HexFilter)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_Latin1FromUTF8"></a>CNV_Latin1FromUTF8
-------------------------------------------------

Converts a UTF-8 string into a Latin-1 string, if possible.
  

@deprecated	 Use [CNV_Latin1FromUTF8Bytes()](#CNV_Latin1FromUTF8Bytes) instead.

### VBA/VB6 Syntax

`Public Declare Function CNV_Latin1FromUTF8 Lib "diCrPKI.dll" 
    (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strInput As String) As Long`

`nLen = CNV_Latin1FromUTF8(strOutput, nOutChars, strInput)`

### C/C++ Syntax

`long __stdcall CNV_Latin1FromUTF8(char *szOutput, long nOutChars, const char *szInput);`

### Parameters

*szOutput*
:   [out] to receive the output.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szInput*
:   [in] of UTF-8 characters to be converted.

### Returns (VBA/C)

If successful, the return value is a positive number indicating the 
number of characters in the output string, or number of characters required if *nOutChars* is set to zero; 
otherwise it returns a negative [error code](#errorcodes).

### .NET Equivalent

Not applicable in .NET.

### Remarks

### Example

### See Also

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_Latin1FromUTF8Bytes"></a>CNV_Latin1FromUTF8Bytes
-----------------------------------------------------------

Converts UTF-8 encoded array of bytes into a Latin-1 string, if possible.

### VBA/VB6 Syntax

`Public Declare Function CNV_Latin1FromUTF8Bytes Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByRef lpInput As Byte, ByVal nBytes As Long) As Long`

`nLen = CNV_Latin1FromUTF8Bytes(strOutput, nOutChars, lpInput(0), nBytes)`

### C/C++ Syntax

`long __stdcall CNV_Latin1FromUTF8Bytes(char *szOutput, long nOutChars, const unsigned char *lpInput, long nBytes);`

### Parameters

*szOutput*
:   [out] to receive the output.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*lpInput*
:   [in] array containing UTF-8 encoded data.

*nBytes*
:   [in] number of bytes in input array.

### Returns (VBA/C)

If successful, the return value is a positive number indicating the 
number of characters (bytes) in the output string, or number of characters required if *nOutChars* is set to zero; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cnvLatin1FromUTF8Bytes`](#VB_cnvLatin1FromUTF8Bytes) (lpInput() As Byte) As String

### .NET Equivalent

Use `System.Text.Encoding.UTF8.GetString(bytes)`.

### C++ (STL) Equivalent

static std::string [dipki::Cnv::Latin1FromUTF8Bytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a53aff21e51cfd1b4b496d61d1cf8959a "External link") (const bvec_t &bv)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The input must be valid UTF-8 data.
Possible errors are INVALID_DATA_ERROR indicating invalid UTF-8 input and OUT_OF_RANGE_ERROR which indicates
that the output would contain a character greater than 8 bits in size.

### Example (VBA core function)

See [`CNV_UTF8BytesFromLatin1`](#CNV_UTF8BytesFromLatin1).

### Example (VBA wrapper function)

```

Dim strData As String
Dim lpDataUTF8() As Byte
strData = "abcóéÍáñ"
Debug.Print "Latin-1 string='" & strData & "'"
Debug.Print " (" & Len(strData) & " characters)"
lpDataUTF8 = cnvUTF8BytesFromLatin1(strData)
Debug.Print "UTF-8=(0x)" & cnvHexStrFromBytes(lpDataUTF8)
Debug.Print " (" & cnvBytesLen(lpDataUTF8) & " bytes)"
Debug.Print "cnvCheckUTF8Bytes returns " & cnvCheckUTF8Bytes(lpDataUTF8) & " (expected 2)"
' And back to a string
Dim strLatin1 As String
strLatin1 = cnvLatin1FromUTF8Bytes(lpDataUTF8)
Debug.Print "Back to string='" & strLatin1 & "'"

```

```

Dim strPrivateKey As String
Dim lpData() As Byte
Dim strData As String

' Read in private key to internal key string
strPrivateKey = rsaReadPrivateKey("BobPrivRSAEncrypt.p8e", "password")
Debug.Assert Len(strPrivateKey) > 0

' 1. Decrypted content is UTF-8 encoded
lpData = cmsReadEnvDataToBytes("cmsalice2bob_utf8.p7m", "", strPrivateKey, 0)
Debug.Assert cnvBytesLen(lpData) > 0
Debug.Print "HEX(PT)=" & cnvHexStrFromBytes(lpData)
' Convert from UTF-8-encoded bytes to VB Unicode string
strData = cnvLatin1FromUTF8Bytes(lpData)
Debug.Print "PT=" & strData

' 2. Decrypted content is plain ANSI string
strData = cmsReadEnvDataToString("cms2bobandcarl.p7m", "", strPrivateKey, 0)
Debug.Print "PT=" & strData

' Clean up
strPrivateKey = wipeString(strPrivateKey)

```

```

Dim lpData() As Byte
Dim strData As String

' Read UTF-8 encoded data from signed-data CMS object
lpData = cmsReadSigDataToBytes("basicsignedbyalice_utf8.p7m")
Debug.Assert cnvBytesLen(lpData) > 0
Debug.Print "HEX(CONTENT)=" & cnvHexStrFromBytes(lpData)
' Convert from UTF-8-encoded bytes to VB Unicode string
strData = cnvLatin1FromUTF8Bytes(lpData)
Debug.Print "CONTENT='" & strData & "'"
```

### See Also

[CNV_UTF8BytesFromLatin1](#CNV_UTF8BytesFromLatin1)
[CNV_CheckUTF8Bytes](#CNV_CheckUTF8)
[CNV_ByteEncoding](#CNV_ByteEncoding)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_NumFromBytes"></a>CNV_NumFromBytes
---------------------------------------------

Converts the leftmost four bytes of an array to a 32-bit integer.

### VBA/VB6 Syntax

`Public Declare Function CNV_NumFromBytes Lib "diCrPKI.dll" (ByRef lpInput As Byte, ByVal nBytes As Long, ByVal nOptions As Long) As Long`

`nRet = CNV_NumFromBytes(lpInput(0), nBytes, nOptions)`

### C/C++ Syntax

`long __stdcall CNV_NumFromBytes(const unsigned char *lpInput, long nBytes, long nOptions);`

### Parameters

*lpInput*
:   [in] Byte array to be converted.

*nBytes*
:   [in] number of bytes.

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_CNV_BIG_ENDIAN` (0) for big-endian order (default)  

`PKI_CNV_LITTLE_ENDIAN` for little-endian order

### Returns (VBA/C)

Decoded integer value, or zero on error.

### VBA Wrapper Syntax

Public Function [`cnvNumFromBytes`](#VB_cnvNumFromBytes) (lpInput() As Byte, Optional nOptions As Long = 0) As Long

### .NET Equivalent

[Cnv.NumFromBytes Method](#M_Cnv_NumFromBytes)  

### C++ (STL) Equivalent

static uint32_t [dipki::Cnv::NumFromBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a258627606677910096c29c970efb3110 "External link") (const bvec_t &bv, EndianNess endn=EndianNess::BigEndian)

### Python Equivalent

static [Cnv.num_from_bytes](https://cryptosys.net/pki/pydocpki/class-stubs/Cnv.html#cryptosyspki.Cnv.num_from_bytes "External link")(data, endn=EndianNess.BIG_ENDIAN)

### Remarks

An array shorter than 4 bytes will be padded on the right with zeros.

### Example

```

Dim abData() As Byte
Dim nBytes As Long
Dim nRet As Long

abData = cnvBytesFromHexStr("DEADBEEF")
nBytes = UBound(abData) + 1
Debug.Print "INPUT:  " & cnvHexStrFromBytes(abData)
' Default big-endian order
nRet = CNV_NumFromBytes(abData(0), nBytes, 0)
Debug.Print "CNV_NumFromBytes(BE)=0x" & Hex(nRet)
' Little-endian order
nRet = CNV_NumFromBytes(abData(0), nBytes, PKI_CNV_LITTLE_ENDIAN)
Debug.Print "CNV_NumFromBytes(LE)=0x" & Hex(nRet)
' Input shorter than 4 bytes is padded on the right with zeros
nRet = CNV_NumFromBytes(abData(0), 3, PKI_CNV_BIG_ENDIAN)
Debug.Print "CNV_NumFromBytes(BE)=0x" & Hex(nRet)
nRet = CNV_NumFromBytes(abData(0), 3, PKI_CNV_LITTLE_ENDIAN)
Debug.Print "CNV_NumFromBytes(LE)=0x" & Hex(nRet)

```

```

INPUT:  DEADBEEF
CNV_NumFromBytes(BE)=0xDEADBEEF
CNV_NumFromBytes(LE)=0xEFBEADDE
CNV_NumFromBytes(BE)=0xDEADBE00
CNV_NumFromBytes(LE)=0xBEADDE

```

### See Also

[CNV_NumToBytes](#CNV_NumToBytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_NumToBytes"></a>CNV_NumToBytes
-----------------------------------------

Converts a 32-bit integer to an array of 4 bytes.

### VBA/VB6 Syntax

`Public Declare Function CNV_NumToBytes Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByVal nNumber As Long, ByVal nOptions As Long) As Long`

`nRet = CNV_NumToBytes(lpOutput(0), nOutBytes, nNumber, nOptions)`

### C/C++ Syntax

`long __stdcall CNV_NumToBytes(unsigned char *lpOutput, long nOutBytes, long nNumber, long nOptions);`

### Parameters

*lpOutput*
:   [out] byte array to receive output.

*nOutBytes*
:   [in] size of output array in bytes.

*nNumber*
:   [in] integer to be converted.

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_CNV_BIG_ENDIAN` (0) for big-endian order (default)  

`PKI_CNV_LITTLE_ENDIAN` for little-endian order

### Returns (VBA/C)

If successful, the return value is zero; 
otherwise it returns a nonzero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cnvNumToBytes`](#VB_cnvNumToBytes) (nNumber As Long, Optional nOptions As Long = 0) As Byte()

### .NET Equivalent

[Cnv.NumToBytes Method](#M_Cnv_NumToBytes)  

### C++ (STL) Equivalent

static bvec_t [dipki::Cnv::NumToBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a981d66f0e73e13f80707c841fe62c3a2 "External link") (uint32_t n, EndianNess endn=EndianNess::BigEndian)

### Python Equivalent

static [Cnv.num_to_bytes](https://cryptosys.net/pki/pydocpki/class-stubs/Cnv.html#cryptosyspki.Cnv.num_to_bytes "External link")(num, endn=EndianNess.BIG_ENDIAN)

### Remarks

The output byte array *lpOutput* will contain the representation of the integer in given order.
A negative *nNumber* will be interpreted in equivalent twos-complement unsigned form.

### Example (VBA core function)

```

Dim abData() As Byte
Dim nBytes As Long
Dim nNumber As Long
Dim nRet As Long

nBytes = 4
ReDim abData(nBytes - 1)
nNumber = &HDEADBEEF
Debug.Print "INPUT=0x" & Hex(nNumber) & " (" & nNumber & ")"
' Default big-endian order
nRet = CNV_NumToBytes(abData(0), nBytes, nNumber, 0)
Debug.Print "CNV_NumToBytes(BE)=" & cnvHexStrFromBytes(abData)
' Little-endian order
nRet = CNV_NumToBytes(abData(0), nBytes, nNumber, PKI_CNV_LITTLE_ENDIAN)
Debug.Print "CNV_NumToBytes(LE)=" & cnvHexStrFromBytes(abData)

```

```

INPUT=0xDEADBEEF (-559038737)
CNV_NumToBytes(BE)=DEADBEEF
CNV_NumToBytes(LE)=EFBEADDE

```

### Example (VBA wrapper function)

```

Dim lpData() As Byte
Dim nBytes As Long
Dim nNumber As Long

nNumber = &HDEADBEEF
Debug.Print "INPUT=0x" & Hex(nNumber) & " (" & nNumber & ")"
' Default big-endian order
lpData = cnvNumToBytes(nNumber)
Debug.Print "cnvNumToBytes(BE)=" & cnvHexStrFromBytes(lpData)
' Little-endian order
lpData = cnvNumToBytes(nNumber, PKI_CNV_LITTLE_ENDIAN)
Debug.Print "cnvNumToBytes(LE)=" & cnvHexStrFromBytes(lpData)

```

### See Also

[CNV_NumFromBytes](#CNV_NumFromBytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_ReverseBytes"></a>CNV_ReverseBytes
---------------------------------------------

Reverses the order of a byte array.

### VBA/VB6 Syntax

`Public Declare Function CNV_ReverseBytes Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByRef lpInput As Byte, ByVal nBytes As Long) As Long`

`nRet = CNV_ReverseBytes(lpOutput(0), lpInput(0), nBytes)`

### C/C++ Syntax

`long __stdcall CNV_ReverseBytes(unsigned char *lpOutput, const unsigned char *lpInput, long nBytes);`

### Parameters

*lpOutput*
:   [out] byte array to receive output.

*lpInput*
:   [in] array of bytes to be reversed.

*nBytes*
:   [in] number of bytes.

### Returns (VBA/C)

If successful, the return value is zero; 
otherwise it returns a nonzero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cnvReverseBytes`](#VB_cnvReverseBytes) (lpInput() As Byte) As Byte()

### .NET Equivalent

[Cnv.ReverseBytes Method](#M_Cnv_ReverseBytes)  

### C++ (STL) Equivalent

static bvec_t [dipki::Cnv::ReverseBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a6ae41201c7f200770c2f1d3c4516fb67 "External link") (const bvec_t &data)

### Python Equivalent

static [Cnv.reverse_bytes](https://cryptosys.net/pki/pydocpki/class-stubs/Cnv.html#cryptosyspki.Cnv.reverse_bytes "External link")(data)

### Remarks

The output array *lpOutput* must be at least *nBytes* long. It may be the same variable as *lpInput*.

### Example

```

 Dim abData() As Byte
 Dim nBytes As Long
 Dim nRet As Long
 
 abData = cnvBytesFromHexStr("DEADBEEF01")
 nBytes = UBound(abData) + 1
 Debug.Print "INPUT:  " & cnvHexStrFromBytes(abData)
 nRet = CNV_ReverseBytes(abData(0), abData(0), nBytes)
 Debug.Print "OUTPUT: " & cnvHexStrFromBytes(abData)

```

```

INPUT:  DEADBEEF01
OUTPUT: 01EFBEADDE	

```

### See Also

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_ShortPathName"></a>CNV_ShortPathName
-----------------------------------------------

Retrieve the Windows short path form of the specified path.

### VBA/VB6 Syntax

Not available in VBA/VB6 (no useful equivalent).

### C/C++ Syntax

`long __stdcall CNV_ShortPathName(char *szOut, long nOutChars, const wchar_t* szwFilePath);`

### Parameters

*szOut*
:   [out] Buffer to receive output.

*nOutChars*
:   [in] Maximum length of output string in bytes (excluding the terminating null).

*szwFilePath*
:   [in] Path name in wide characters.

### Returns (VBA/C)

Number of characters (bytes) in or required for the output string; 
otherwise it returns a negative [error code](#errorcodes).

### .NET Equivalent

[Cnv.ShortPathName Method](#M_Cnv_ShortPathName)  

### C++ (STL) Equivalent

static std::string [dipki::Cnv::ShortPathName](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a8d38d8d0febbd2e163e07766ce50921a "External link") (const std::wstring &filePath)

### Python Equivalent

static [Cnv.shortpathname](https://cryptosys.net/pki/pydocpki/class-stubs/Cnv.html#cryptosyspki.Cnv.shortpathname "External link")(pathName)

### Remarks

Use this function to find the ASCII equivalent file path for a path represented in "Unicode" UTF-16 `wchar_t` characters.
Then use this ASCII short name as an argument for an input file in any of the functions in this library that require a file name.

The file must exist. The output path is guaranteed to be in ASCII characters, and the base name and each folder name will be 8 characters or fewer. 
It may not give the same value on a different system. Windows only.

For the "raw" function, pass a NULL *szOut* or zero *nOutChars* to find the required output length in bytes. 
ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

### Example

```

#include <wchar.h>
long nchars;
wchar_t *wfname;
char *shortname;
// Path name with Chinese characters
wfname = L"你好.txt";
// Find required output length
nchars = CNV_ShortPathName(NULL, 0, wfname);
printf("CNV_ShortPathName returns %ld\n", nchars);
assert(nchars >= 0);
shortname = malloc(nchars + 1);
nchars = CNV_ShortPathName(shortname, nchars, wfname);
assert(nchars >= 0);
// Output should be in ASCII
printf("ShortPath='%s'\n", shortname);
// ShortPath='FC0F~1.TXT'
free(shortname);

```

```

#include <string>
// Path name with Chinese characters
std::wstring wfname = L"你好.txt";
std::string shortname = dipki::Cnv::ShortPathName(wfname);
cout << "ShortPath='" << shortname << "'" << endl;

```

```

ShortPath='FC0F~1.TXT'

```

Note that the short path name may be different on your system.

### See Also

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_UTF8FromLatin1"></a>CNV_UTF8FromLatin1
-------------------------------------------------

	
Converts a string of 8-bit Latin-1 characters into UTF-8 format
  

@deprecated Use [CNV_UTF8BytesFromLatin1()](#CNV_UTF8BytesFromLatin1) instead.

### VBA/VB6 Syntax

`Public Declare Function CNV_UTF8FromLatin1 Lib "diCrPKI.dll" 
    (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strInput As String) As Long`

`nLen = CNV_UTF8FromLatin1(strOutput, nOutChars, strInput)`

### C/C++ Syntax

`long __stdcall CNV_UTF8FromLatin1(char *szOutput, long nOutChars, const char *szInput);`

### Parameters

*szOutput*
:   [out] to receive the output.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szInput*
:   [in] of Latin-1 characters to be converted.

### Returns (VBA/C)

If successful, the return value is a positive number indicating the 
number of (single-byte) characters in the output string, or number of characters required if *nOutChars* is set to zero; 
otherwise it returns a negative [error code](#errorcodes).

### .NET Equivalent

Not applicable in .NET.

### Remarks

### Example

### See Also

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_UTF8BytesFromLatin1"></a>CNV_UTF8BytesFromLatin1
-----------------------------------------------------------

Converts a string of 8-bit Latin-1 characters into a UTF-8 encoded array of bytes.

### VBA/VB6 Syntax

`Public Declare Function CNV_UTF8BytesFromLatin1 Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByVal strInput As String) As Long`

`nLen = CNV_UTF8BytesFromLatin1(lpOutput(0), nOutBytes, strInput)`

### C/C++ Syntax

`long __stdcall CNV_UTF8BytesFromLatin1(unsigned char *lpOutput, long nOutBytes, const char *szInput);`

### Parameters

*lpOutput*
:   [out] array suitably dimensioned to receive output.

*nOutBytes*
:   [in] specifying the maximum number of bytes to be received.

*szInput*
:   [in] of Latin-1 characters to be converted.

### Returns (VBA/C)

If successful, the return value is a positive number indicating the 
number of bytes in the output array, or number of bytes required if *nOutBytes* is set to zero; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`cnvUTF8BytesFromLatin1`](#VB_cnvUTF8BytesFromLatin1) (szInput As String) As Byte()

### .NET Equivalent

Use `System.Text.Encoding.UTF8.GetBytes(Str)`.

### C++ (STL) Equivalent

static bvec_t [dipki::Cnv::UTF8BytesFromLatin1](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#ab68bc113efd373567ab51914ee0f88d3 "External link") (const std::string &s)

### Remarks

Will set up to *nOutBytes* bytes in the output array. 
If *nOutBytes* is zero, it returns the required number of bytes.

### Example (VBA core function)

```

Dim strData As String
Dim abDataUTF8() As Byte
Dim nRet As Long
Dim nBytes As Long
Dim nChars As Long
Dim strNew As String

' Our original string data contains 5 non-ASCII characters
strData = "abcóéÍáñ"
Debug.Print "Latin-1 string='" & strData & "'"
Debug.Print " (" & Len(strData) & " characters)"

' Convert directly to array of bytes in UTF-8 encoding
' Find required length first
nBytes = CNV_UTF8BytesFromLatin1(0, 0, strData)
If nBytes <= 0 Then
    Debug.Print "Failed to convert to UTF-8: " & nBytes
    Exit Sub
End If
' Pre-dimension
ReDim abDataUTF8(nBytes - 1)
nBytes = CNV_UTF8BytesFromLatin1(abDataUTF8(0), nBytes, strData)
' Display in hex
Debug.Print "UTF-8=(0x)" & cnvHexStrFromBytes(abDataUTF8)
Debug.Print " (" & nBytes & " bytes)"

' Check if this is valid UTF-8 encoding
nRet = CNV_CheckUTF8Bytes(abDataUTF8(0), nBytes)
Debug.Print "CNV_CheckUTF8Bytes returns " & nRet & " (expected 2)"

' Now put back into a string
nChars = CNV_Latin1FromUTF8Bytes("", 0, abDataUTF8(0), nBytes)
If nChars <= 0 Then
    Debug.Print "Failed to convert to string: " & nChars
    Exit Sub
End If
strNew = String(nChars, " ")
nChars = CNV_Latin1FromUTF8Bytes(strNew, nChars, abDataUTF8(0), nBytes)
Debug.Print "New string='" & strNew & "' (" & nChars & " characters)"

```

This should result in the output:

```

Latin-1 string='abcóéÍáñ'
 (8 characters)
UTF-8=(0x)616263C3B3C3A9C3ADC3A1C3B1
 (13 bytes)
CNV_CheckUTF8Bytes returns 2 (expected 2)
New string='abcóéÍáñ' (8 characters)

```

### Example (VBA wrapper function)

```

Dim strData As String
Dim lpDataUTF8() As Byte
strData = "abcóéÍáñ"
Debug.Print "Latin-1 string='" & strData & "'"
Debug.Print " (" & Len(strData) & " characters)"
lpDataUTF8 = cnvUTF8BytesFromLatin1(strData)
Debug.Print "UTF-8=(0x)" & cnvHexStrFromBytes(lpDataUTF8)
Debug.Print " (" & cnvBytesLen(lpDataUTF8) & " bytes)"
Debug.Print "cnvCheckUTF8Bytes returns " & cnvCheckUTF8Bytes(lpDataUTF8) & " (expected 2)"
' And back to a string
Dim strLatin1 As String
strLatin1 = cnvLatin1FromUTF8Bytes(lpDataUTF8)
Debug.Print "Back to string='" & strLatin1 & "'"

```

```

Dim strData As String
Dim strDigest As String
' Our original string data
strData = "Estándares de Electrónica de México para mañana"
' Compute SHA-1 hash over UTF-8 encoded byte array
strDigest = hashHexFromBytes(cnvUTF8BytesFromLatin1(strData), PKI_HASH_SHA1)
Debug.Print "Digest=" & strDigest
```

### See Also

[CNV_Latin1FromUTF8Bytes](#CNV_Latin1FromUTF8Bytes)
[CNV_CheckUTF8Bytes](#CNV_CheckUTF8Bytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="CNV_Utf8FromWide"></a>CNV_Utf8FromWide
---------------------------------------------

Maps a UTF-16 (wide character) string to a UTF-8-encoded string.

### VBA/VB6 Syntax

No VBA/VB6 equivalent.

### C/C++ Syntax

`long __stdcall CNV_Utf8FromWide(char *szOut, long nOutChars, const wchar_t* wstr);`

### Parameters

*szOut*
:   [out] Buffer to receive null-terminated UTF-8-encoded string.

*nOutChars*
:   [in] Maximum length of output string in bytes (excluding the terminating null).

*wstr*
:   [in] String of wide characters to be processed.

### Returns (VBA/C)

Number of characters (bytes) in or required for the output string; 
otherwise it returns a negative [error code](#errorcodes).

### .NET Equivalent

No .NET equivalent.

### C++ (STL) Equivalent

static std::string [dipki::Cnv::Utf8FromWide](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a9ede836655f91e2caa3288720d6c08fa "External link") (const std::wstring &wstr)

### Remarks

Use this function to convert a C/C++ string of "Unicode" UTF-16 `wchar_t` characters  to a UTF-8-encoded string of type `char`.

For the "raw" ANSI function, pass a NULL *szOut* or zero *nOutChars* to find the required output length in bytes. Allocate one extra byte for the terminating null.

This function is for C/C++ programmers only. There is no VBA or .NET equivalent.

### Example

```

#include <wchar.h>
long nchars;
char *buf = NULL;
wchar_t *wstr = L"áéÍñóü";
// Find required output length (12 in this case)
nchars = CNV_Utf8FromWide(NULL, 0, wstr);
printf("CNV_Utf8FromWide returns %ld\n", nchars);
assert(nchars >= 0);
buf = malloc(nchars + 1);  // NB one extra byte
nchars = CNV_Utf8FromWide(buf, nchars, wstr);
assert(nchars >= 0);
// Assumes console codepage is set to UTF-8
printf("[%s]\n", buf);
free(buf);

```

```

#include <string>
std::string s;
std::wstring wstr;
wstr = L"áéÍñóü";
s = dipki::Cnv::Utf8FromWide(wstr);
cout << "Cnv::Utf8FromWide=[" << s << "]" << endl;
cout << "s-->utf-8 bytes: " << dipki::Cnv::ToHex(dipki::str2bvec(s)) << endl;

```

```

Cnv::Utf8FromWide=[áéÍñóü]
s-->utf-8 bytes: C3A1C3A9C3ADC3B1C3B3C3BC

```

### See Also

[[Contents](#topofpage)] [[Index](#index)]

<a id="COMPR_Compress"></a>COMPR_Compress
-----------------------------------------

Compress data using zlib compression.

### VBA/VB6 Syntax

`Public Declare Function COMPR_Compress Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByRef lpInput As Byte, ByVal nInputLen As Long, ByVal nOptions As Long) As Long`

`nRet = COMPR_Compress(lpOutput(0), nOutputLen, lpInput(0), nInputLen, 0) ' Note the "(0)" after the byte array parameters`

### C/C++ Syntax

`long __stdcall COMPR_Compress(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpInput, long nInputLen, long nOptions);`

### Parameters

*lpOutput*
:   [out] byte buffer to receive output data.

*nOutBytes*
:   [in] size of the output buffer in bytes.

*lpInput*
:   [in] input data to be compressed.

*nInputLen*
:   [in] length of input array in bytes.

*nOptions*
:   [in] option flags. Not used in this release. Set to zero.

### Returns (VBA/C)

The number of bytes successfully copied into the output buffer or the required size in bytes. 
If an error occurs, it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`comprCompress`](#VB_comprCompress) (lpInput() As Byte, Optional nOptions As Long = 0) As Byte()

### .NET Equivalent

[Compr.Compress Method](#M_Compr_Compress)  

### C++ (STL) Equivalent

static bvec_t [dipki::Compr::Compress](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_compr.html#adb335ad3ad155607aae0211338a9b699 "External link") (const bvec_t &data)

### Python Equivalent

static [Compr.compress](https://cryptosys.net/pki/pydocpki/class-stubs/Compr.html#cryptosyspki.Compr.compress "External link")(data)

### Remarks

To determine the required size of the output buffer, call the function with *nOutBytes* set to zero (or *lpOutput* set to NULL).

### Example (VBA core function)

```

Dim strPlain As String
Dim strBack As String
Dim abPlain() As Byte
Dim abCompressed() As Byte
Dim nCompLen As Long
Dim nUncompLen As Long
Dim nRet As Long

' COMPRESSSION (deflation)

' Set the plaintext message
strPlain = "hello, hello, hello. This is a 'hello world' message " & _
    "for the world, repeat, for the world."
' Convert to an array of bytes
abPlain = StrConv(strPlain, vbFromUnicode)
nUncompLen = UBound(abPlain) + 1
' Find required compressed length by calling with zero length value
nCompLen = COMPR_Compress(0, 0, abPlain(0), nUncompLen, 0)
ReDim abCompressed(nCompLen - 1)
' Now compress plaintext
Call COMPR_Compress(abCompressed(0), nCompLen, abPlain(0), nUncompLen, 0)
Debug.Print "Compressed " & nUncompLen & " bytes to " & nCompLen

' DECOMPRESSSION (inflation)

' Uncompress the compressed data
' Find the required length of uncompressed data
nUncompLen = COMPR_Uncompress(0, 0, abCompressed(0), nCompLen, 0)
Debug.Print "Required uncompressed length is " & nUncompLen & " bytes"
ReDim abPlain(nUncompLen - 1)
nRet = COMPR_Uncompress(abPlain(0), nUncompLen, abCompressed(0), nCompLen, 0)

' Convert back to a string
strBack = StrConv(abPlain, vbUnicode)
Debug.Print strBack

```

```

Compressed 90 bytes to 68
Required uncompressed length is 90 bytes
hello, hello, hello. This is a 'hello world' message for the world, repeat, for the world.

```

### Example (VBA wrapper function)

```

Dim strPlain As String
Dim lpToCompress() As Byte
Dim lpCompressed() As Byte
Dim lpUncompressed() As Byte
strPlain = "hello, hello, hello. This is a 'hello world' message " & _
    "for the world, repeat, for the world."
lpToCompress = StrConv(strPlain, vbFromUnicode)
lpCompressed = comprCompress(lpToCompress)
Debug.Print "OK=        " & "789CCB48CDC9C9D751C840A2F4144232328B15802851411D2CA2509E5F9493A2AE909B5A5C9C989EAA90965FA45092910A11D651284A2D484D2CD14115D6030086D11F4E"
Debug.Print "COMPRESSED=" & cnvHexStrFromBytes(lpCompressed)
lpUncompressed = comprUncompress(lpCompressed)
Debug.Print "'" & StrConv(lpUncompressed, vbUnicode); "'"

```

### See Also

[`COMPR_Uncompress`](#COMPR_Uncompress)

[[Contents](#topofpage)] [[Index](#index)]

<a id="COMPR_Uncompress"></a>COMPR_Uncompress
---------------------------------------------

Uncompress data using zlib compression.

### VBA/VB6 Syntax

`Public Declare Function COMPR_Uncompress Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByRef lpInput As Byte, ByVal nInputLen As Long, ByVal nOptions As Long) As Long`

`nRet = COMPR_Uncompress(lpOutput(0), nOutputLen, lpInput(0), nInputLen, 0) ' Note the "(0)" after the byte array parameters`

### C/C++ Syntax

`long __stdcall COMPR_Uncompress(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpInput, long nInputLen, long nOptions);`

### Parameters

*lpOutput*
:   [out] byte buffer to receive output data.

*nOutBytes*
:   [in] size of the output buffer in bytes.

*lpInput*
:   [in] input data to be uncompressed.

*nInputLen*
:   [in] length of input array in bytes.

*nOptions*
:   [in] option flags. Not used in this release. Set to zero.

### Returns (VBA/C)

The number of bytes successfully copied into the output buffer or the required size in bytes. 
If an error occurs, it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`comprUncompress`](#VB_comprUncompress) (lpInput() As Byte, Optional nOptions As Long = 0) As Byte()

### .NET Equivalent

[Compr.Uncompress Method](#M_Compr_Uncompress)  

### C++ (STL) Equivalent

static bvec_t [dipki::Compr::Uncompress](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_compr.html#a24cae59498eff5ebf00d075cb1dc7b02 "External link") (const bvec_t &data)

### Python Equivalent

static [Compr.uncompress](https://cryptosys.net/pki/pydocpki/class-stubs/Compr.html#cryptosyspki.Compr.uncompress "External link")(data)

### Remarks

To determine the required size of the output buffer, call the function with *nOutBytes* set to zero (or *lpOutput* set to NULL).

### Example (VBA core function)

See [`COMPR_Compress`](#COMPR_Compress).

### Example (VBA wrapper function)

```

Dim strPlain As String
Dim lpToCompress() As Byte
Dim lpCompressed() As Byte
Dim lpUncompressed() As Byte
strPlain = "hello, hello, hello. This is a 'hello world' message " & _
    "for the world, repeat, for the world."
lpToCompress = StrConv(strPlain, vbFromUnicode)
lpCompressed = comprCompress(lpToCompress)
Debug.Print "OK=        " & "789CCB48CDC9C9D751C840A2F4144232328B15802851411D2CA2509E5F9493A2AE909B5A5C9C989EAA90965FA45092910A11D651284A2D484D2CD14115D6030086D11F4E"
Debug.Print "COMPRESSED=" & cnvHexStrFromBytes(lpCompressed)
lpUncompressed = comprUncompress(lpCompressed)
Debug.Print "'" & StrConv(lpUncompressed, vbUnicode); "'"

```

### See Also

[`COMPR_Compress`](#COMPR_Compress)

[[Contents](#topofpage)] [[Index](#index)]

<a id="ECC_DHSharedSecret"></a>ECC_DHSharedSecret
-------------------------------------------------

Compute EC Diffie-Hellman (ECDH) shared secret.

### VBA/VB6 Syntax

`Public Declare Function ECC_DHSharedSecret Lib "diCrPKI.dll" (ByRef lpZZ As Byte, ByVal nOutBytes As Long, ByVal strIntPrivateKey As String, ByVal strIntPublicKey As String, ByVal nOptions As Long) As Long`

`nRet = ECC_DHSharedSecret(lpZZ(0), nOutBytes, strIntPrivateKey, strIntPublicKey, nOptions)`

### C/C++ Syntax

`long __stdcall ECC_DHSharedSecret(unsigned char *lpZZ, long nOutBytes, const char *szIntPrivateKey, const char *szIntPublicKey, long nOptions);`

### Parameters

*lpZZ*
:   [out] Buffer to receive shared secret as an array of bytes.

*nOutBytes*
:   [in] Length of output buffer in bytes.

*szIntPrivateKey*
:   [in] String containing our own private key in ephemeral "internal" form.

*szIntPublicKey*
:   [in] String containing other party's public key in "internal" form.

*nOptions*
:   [in] Not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is the number of bytes in or required in the output; otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`eccDHSharedSecret`](#VB_eccDHSharedSecret) (szIntPrivateKey As String, szIntPublicKey As String, Optional nOptions As Long = 0) As Byte()

### .NET Equivalent

[Ecc.DHSharedSecret Method](#M_Ecc_DHSharedSecret)  

### C++ (STL) Equivalent

static bvec_t [dipki::Ecc::DHSharedSecret](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#a641375295d539a47a74f1415cc62b126 "External link") (std::string ourIntPrivateKey, std::string theirIntPublicKey)

### Python Equivalent

static [Ecc.dh_shared_secret](https://cryptosys.net/pki/pydocpki/class-stubs/Ecc.html#cryptosyspki.Ecc.dh_shared_secret "External link")(intprikeystr, intpubkeystr)

### Remarks

The output is the Diffie-Hellman shared secret. This may require further processing to be used in an application; for example, as input to a key derivation function.
The keys are expected in ephemeral "internal" format read into a string using 
[`ECC_ReadPrivateKey`](#ECC_ReadPrivateKey),
[`ECC_ReadPublicKey`](#ECC_ReadPublicKey) or
[`ECC_ReadKeyByCurve`](#ECC_ReadKeyByCurve).
All supported NIST/SEC curves can be used as well as the safe curve X25519 (but not Ed25519 or Ed448, which are for signatures only).

### Example (VBA core function)

```

Dim strOurPriKeyHex As String
Dim strTheirPubKeyHex As String
Dim strOurPrivateKey As String
Dim strTheirPublicKey As String
Dim strCurveName As String
Dim strCorrectHex As String
Dim lpZZ() As Byte
Dim nChars As Long
Dim nBytes As Long
Dim nBits As Long

' Ref: CAVS 14.1 ECC CDH Primitive (SP800 - 56A Section 5.7.1.2)
' Test Information for "testecccdh" ecccdhtestvectors.zip

'[P-256]

strCurveName = "P-256"
' Our private key is dUIT:
strOurPriKeyHex = "7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534"
' Their public key as hex is "04" || QCAVSx || QCAVSy
strTheirPubKeyHex = "04" & "700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287" _
	+ "db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac"
' Correct result is ZIUT
strCorrectHex = "46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b"

Debug.Print "Test for curve " & strCurveName & " ..."
' Read in keys to internal key strings
' Our private key...
nChars = ECC_ReadKeyByCurve("", 0, strOurPriKeyHex, strCurveName, 0)
Debug.Assert nChars > 0
strOurPrivateKey = String(nChars, " ")
nChars = ECC_ReadKeyByCurve(strOurPrivateKey, nChars, strOurPriKeyHex, strCurveName, 0)
Debug.Assert nChars > 0
' Check the key we read in
nBits = ECC_QueryKey("", 0, strOurPrivateKey, "keyBits", 0)
Debug.Print "Our private key has " & nBits & " bits"

' Their public key...
nChars = ECC_ReadKeyByCurve("", 0, strTheirPubKeyHex, strCurveName, 0)
Debug.Assert nChars > 0
strTheirPublicKey = String(nChars, " ")
nChars = ECC_ReadKeyByCurve(strTheirPublicKey, nChars, strTheirPubKeyHex, strCurveName, 0)
Debug.Assert nChars > 0
' Check the key we read in
nBits = ECC_QueryKey("", 0, strTheirPublicKey, "keyBits", 0)
Debug.Print "Their public key has " & nBits & " bits"

' Compute shared secret
' - find required length
nBytes = ECC_DHSharedSecret(ByVal 0&, 0, strOurPrivateKey, strTheirPublicKey, 0)
Debug.Print "ECC_DHSharedSecret returns " & nBytes & " (expecting +ve)"
Debug.Assert nBytes > 0
' - allocate memory
ReDim lpZZ(nBytes - 1)
' - do the business
nBytes = ECC_DHSharedSecret(lpZZ(0), nBytes, strOurPrivateKey, strTheirPublicKey, 0)
Debug.Assert nBytes > 0

Debug.Print "ZZ=" & cnvHexStrFromBytes(lpZZ)
' Check the result
Debug.Print "OK=" & strCorrectHex
Debug.Assert UCase(cnvHexStrFromBytes(lpZZ)) = UCase(strCorrectHex)

```

```

Test for curve P-256 ...
Our private key has 256 bits
Their public key has 256 bits
ECC_DHSharedSecret returns 32 (expecting +ve)
ZZ=46FC62106420FF012E54A434FBDD2D25CCC5852060561E68040DD7778997BD7B
OK=46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b

```

### Example (VBA wrapper function)

```

Dim strCurveName As String
Dim ourPrivateKey As String
Dim theirPublicKey As String
Dim lpZZ() As Byte

' Ref: RFC7748 Section 6.1
Const alicePrivateKeyHex As String = "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a"
Const alicePublicKeyHex As String = "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a"
Const bobPrivateKeyHex As String = "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb"
Const bobPublicKeyHex As String = "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f"

strCurveName = "X25519"
' 1. Alice's private + Bob's public
ourPrivateKey = eccReadKeyByCurve(alicePrivateKeyHex, strCurveName, PKI_ECC_PRIVATE_KEY)
Debug.Print "Our key has " & eccQueryKey(ourPrivateKey, "keyBits") & " bits and is a " & _
    IIf(eccQueryKey(ourPrivateKey, "isPrivate") = "1", "Private", "Public") & " key"
theirPublicKey = eccReadKeyByCurve(bobPublicKeyHex, strCurveName, PKI_ECC_PUBLIC_KEY)
Debug.Print "Their key has " & eccQueryKey(theirPublicKey, "keyBits") & " bits and is a " & _
    IIf(eccQueryKey(theirPublicKey, "isPrivate") = "1", "Private", "Public") & " key"
' Compute shared secret
lpZZ = eccDHSharedSecret(ourPrivateKey, theirPublicKey)
Debug.Print "ZZ=" & cnvHexStrFromBytes(lpZZ)
Debug.Print "OK=4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"

' 2. Bob's private + Alice's public
ourPrivateKey = eccReadKeyByCurve(bobPrivateKeyHex, strCurveName, PKI_ECC_PRIVATE_KEY)
Debug.Print "Our key has " & eccQueryKey(ourPrivateKey, "keyBits") & " bits and is a " & _
    IIf(eccQueryKey(ourPrivateKey, "isPrivate") = "1", "Private", "Public") & " key"
theirPublicKey = eccReadKeyByCurve(alicePublicKeyHex, strCurveName, PKI_ECC_PUBLIC_KEY)
Debug.Print "Their key has " & eccQueryKey(theirPublicKey, "keyBits") & " bits and is a " & _
    IIf(eccQueryKey(theirPublicKey, "isPrivate") = "1", "Private", "Public") & " key"
' Compute shared secret
lpZZ = eccDHSharedSecret(ourPrivateKey, theirPublicKey)
Debug.Print "ZZ=" & cnvHexStrFromBytes(lpZZ)
Debug.Print "OK=4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"
```

### See Also

[[Contents](#topofpage)] [[Index](#index)]

<a id="ECC_KeyHashCode"></a>ECC_KeyHashCode
-------------------------------------------

Computes the hash code of an "internal" ECC public or private key string.

### VBA/VB6 Syntax

`Public Declare Function ECC_KeyHashCode Lib "diCrPKI.dll" 
    (ByVal strKeyString As String) As Long`

`nRet = ECC_KeyHashCode(strKeyString)`

### C/C++ Syntax

`long __stdcall ECC_KeyHashCode(const char *szKeyString);`

### Parameters

*szKeyString*
:   [in] containing the ECC private or public key string in internal format.

### Returns (VBA/C)

A 32-bit hash code for the key, or zero on error.

### VBA Wrapper Syntax

Public Function [`eccKeyHashCode`](#VB_eccKeyHashCode) (szIntKeyString As String) As Long

### .NET Equivalent

[Ecc.KeyHashCode Method](#M_Ecc_KeyHashCode)  

### C++ (STL) Equivalent

static uint32_t [dipki::Ecc::KeyHashCode](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#ab038341ad84051f76c27a4961b899603 "External link") (std::string intKeyString)

### Python Equivalent

static [Ecc.key_hashcode](https://cryptosys.net/pki/pydocpki/class-stubs/Ecc.html#cryptosyspki.Ecc.key_hashcode "External link")(intkeystr)

### Remarks

Use this function to compare internal key strings. 
The hash code value will be the same for a given key. 
The hash code is computed to an internal algorithm and may return any integer value 
between -2,147,483,648 and 2,147,483,647.

If the key string is invalid, the return value is zero and a nonzero error code will be set (use [`PKI_ErrorCode`](#PKI_ErrorCode) to check).
There is a very small chance (one in 4 billion) that a valid key string returns a hash code of zero.

### Example

```

Dim nRet As Long
Dim nChars As Long
Dim strPubKeyFile As String
Dim strPriKeyFile As String
Dim strIntKey As String
Dim strPassword As String

strPubKeyFile = "CA_ECC_P256.pub"
strPriKeyFile = "CA_ECC_P256.p8e"
strPassword = "password"

' 1. Read in private key to internal key string
Debug.Print "FILE: " & strPriKeyFile
' Find required length of internal key string
nChars = ECC_ReadPrivateKey("", 0, strPriKeyFile, strPassword, 0)
Debug.Print "ECC_ReadPrivateKey returns " & nChars & " (expected +ve)"
' Dimension the string to receive output
strIntKey = String(nChars, " ")
' Read it in
nChars = ECC_ReadPrivateKey(strIntKey, Len(strIntKey), strPriKeyFile, strPassword, 0)
' Note: internal key string is only valid for the current session
' But the Key Hash Code is always the same
nRet = ECC_KeyHashCode(strIntKey)
Debug.Print "KeyHashCodePrivate=0x" & Hex(nRet)

' 2. Read in public key to internal string
Debug.Print "FILE: " & strPubKeyFile
' Find required length of internal key string
nChars = ECC_ReadPublicKey("", 0, strPubKeyFile, 0)
Debug.Print "ECC_ReadPublicKey returns " & nChars & " (expected +ve)"
' Dimension the string to receive output
strIntKey = String(nChars, " ")
' Read it in
nChars = ECC_ReadPublicKey(strIntKey, Len(strIntKey), strPubKeyFile, 0)
' The public and private Key Hash Codes should match
nRet = ECC_KeyHashCode(strIntKey)
Debug.Print "KeyHashCodePublic=0x" & Hex(nRet)

```

```

FILE: CA_ECC_P256.p8e
ECC_ReadPrivateKey returns 100 (expected +ve)
KeyHashCodePrivate=0x37210904
FILE: CA_ECC_P256.pub
ECC_ReadPublicKey returns 124 (expected +ve)
KeyHashCodePublic=0x37210904

```

### See Also

[[Contents](#topofpage)] [[Index](#index)]

<a id="ECC_MakeKeys"></a>ECC_MakeKeys
-------------------------------------

Generates an EC public/private key pair and saves as two key files.

### VBA/VB6 Syntax

`Public Declare Function ECC_MakeKeys Lib "diCrPKI.dll" (ByVal strPubKeyFile As String, ByVal strPriKeyFile As String, ByVal strCurveName As String, ByVal strPassword As String, ByVal strParams As String, ByVal nOptions As Long) As Long`

`nRet = ECC_MakeKeys(strPublicKeyFile, strPrivateKeyFile, strCurveName, strPassword, strParams, nOptions)`

### C/C++ Syntax

`long __stdcall ECC_MakeKeys(const char *szPubKeyFile, const char *szPriKeyFile, const char *szCurveName, const char *szPassword, const char *szParams, long nOptions);`

### Parameters

*szPubKeyFile*
:   [in] name of public key file to be created.

*szPriKeyFile*
:   [in] name of encrypted private key file to be created.

*szCurveName*
:   [in] name of elliptic curve (see remarks).

*szPassword*
:   [in] the password to be used for the encrypted key file.

*szParams*
:   [in] (optional) parameters. Set as the empty string `""` for defaults.
	Otherwise include a set of attribute-value pairs separated by a semi-colon ";" to set options from the following
* `count=<nnn>` to set the iteration count in the encrypted private key used in the PBKDF method,
	e.g. `"count=5000;"` [default=`2048`]
* `prf=<hmac-name>` to change the HMAC algorithm used in the PBKDF2 method,
	e.g. `"prf=hmacWithSHA256;"` [default=`hmacwithSHA1`]
* `rngseed=<string>` to add some extra user-specified additional seed for the random number generator,
	e.g. `"rngseed=pqrrr1234xyz;"`

Valid values for hmac-name are `{hmacWithSHA1|hmacWithSHA224|hmacWithSHA256|hmacWithSHA384|hmacWithSHA512}`.

*nOptions*
:   [in] containing a flag to indicate the password-based encryption scheme to be used 
to encrypt the private key file. Select from:  

`PKI_PBE_SHA_3DES` (0) for `"pbeWithSHAAnd3-KeyTripleDES-CBC"` (default)  

`PKI_PBE_PBKDF2_DESEDE3` for PBKDF2 using `des-EDE3-CBC`  

`PKI_PBE_PBKDF2_AES128` for PBKDF2 using `aes128-CBC`  

`PKI_PBE_PBKDF2_AES192` for PBKDF2 using `aes192-CBC`  

`PKI_PBE_PBKDF2_AES256` for PBKDF2 using `aes256-CBC`  

(there are more options - see [security options for encrypted private keys](#encryptedkeyoptions))  

and optionally add  

`PKI_KEY_FORMAT_PEM` to save the key files in PEM form (default is binary DER-encoded format).

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`eccMakeKeys`](#VB_eccMakeKeys) (szPubKeyFile As String, szPriKeyFile As String, szCurveName As String, szPassword As String, Optional szParams As String = "", Optional nOptions As Long = 0) As Long

### .NET Equivalent

[Ecc.MakeKeys Method](#M_Ecc_MakeKeys)  

### C++ (STL) Equivalent

static int [dipki::Ecc::MakeKeys](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#a61c359b0da5243cb7e028d0a2e7cce08 "External link") (const std::string &publicKeyFile, const std::string &privateKeyFile, Curve curve, const std::string &password, PbeScheme pbes=PbeScheme::Default, const std::string &paramString="", Format fileFormat=Format::Binary)

### Python Equivalent

static [Ecc.make_keys](https://cryptosys.net/pki/pydocpki/class-stubs/Ecc.html#cryptosyspki.Ecc.make_keys "External link")(pubkeyfile, prikeyfile, curvename, password, pbescheme=0, params='', fileformat=0)

### Remarks

The public and private keys are encoded into ASN.1 values of type 
`SubjectPublicKeyInfo` and `EncryptedPrivateKeyInfo` respectively.
Any existing files of the same names will be overwritten without warning.
The password should be a string of non-zero ASCII characters.

The key is stored by default as a pair of DER-encoded binary files. 
Use the `PKI_KEY_FORMAT_PEM` flag to save in PEM-encoded format. 

Supported curve names for *szCurveName* are: 

| Curve name | Alternative names | Remarks |
| --- | --- | --- |
| `secp192r1` | `P-192`, `P_192`, `prime192v1` | NIST |
| `secp256r1` | `P-256`, `P_256`, `prime256v1` | NIST |
| `secp224r1` | `P-224`, `P_224` | NIST |
| `secp384r1` | `P-384`, `P_384` | NIST |
| `secp521r1` | `P-521`, `P_521` | NIST |
| `secp256k1` |  | Bitcoin/SEC |
| `Ed25519` |  | For EdDSA signatures |
| `X25519` |  | For ECDH key exchange |
| `Ed448` |  | For EdDSA signatures |
| `X448` |  | For ECDH key exchange |
| `brainpoolP256r1` |  | [RFC5639] |
| `brainpoolP384r1` |  | [RFC5639] |
| `brainpoolP512r1` |  | [RFC5639] |

Valid values for the "prf" parameter in *szParams* are:

* `hmacWithSHA1` (default)
* `hmacWithSHA224`
* `hmacWithSHA256`
* `hmacWithSHA384`
* `hmacWithSHA512`

These are case-insensitive and work only with the `PKI_PBE_PBKDF2_` options. This will override any `PKI_HMAC_` flag in *nOptions*

Set *szParams* as the empty string `""` for defaults.

### Example

The following example creates two new key pairs for the NIST curves P-256 and P-521, respectively.
The first example saves the private key using default options (`pbeWithSHAAnd3-KeyTripleDES-CBC` with an iteration count of 2048).
The second example saves the private key using PBKDF2 with AES-256 as the encryption scheme, hmacWithSHA512 as the PRF algorithm, and an iteration count of 5000.

```

Dim nRet As Long
Dim strPublicKeyFile As String
Dim strPrivateKeyFile As String
Dim strPassword As String
Dim strCurve As String
Dim nChars As Long
Dim strTypeName As String
Dim strFileName As String

strPublicKeyFile = "myeckeyp256.pub"
strPrivateKeyFile = "myeckeyp256.p8"
strPassword = "password"
strCurve = "P-256"
' Create a new pair of ECC keys saved as DER-encoded files
nRet = ECC_MakeKeys(strPublicKeyFile, strPrivateKeyFile, strCurve, strPassword, "", 0)
Debug.Print "ECC_MakeKeys returns " & nRet & " (expected 0)"

strPublicKeyFile = "myeckeyp521.pub"
strPrivateKeyFile = "myeckeyp521.p8"
strPassword = "password"
strCurve = "P-521"
' Create a new pair of ECC keys saved as DER-encoded files
nRet = ECC_MakeKeys(strPublicKeyFile, strPrivateKeyFile, strCurve, strPassword, "count=5000;prf=hmacWithSHA512;", PKI_PBE_PBKDF2_AES256)
Debug.Print "ECC_MakeKeys returns " & nRet & " (expected 0)"

' Check the types of files we made
strTypeName = String(PKI_ASN1_TYPE_MAXCHARS, " ")
strFileName = strPublicKeyFile
nChars = ASN1_Type(strTypeName, Len(strTypeName), strFileName, 0)
If nChars > 0 Then Debug.Print strFileName & ": " & Left(strTypeName, nChars)
strFileName = strPrivateKeyFile
nChars = ASN1_Type(strTypeName, Len(strTypeName), strFileName, 0)
If nChars > 0 Then Debug.Print strFileName & ": " & Left(strTypeName, nChars)

```

```

ECC_MakeKeys returns 0 (expected 0)
ECC_MakeKeys returns 0 (expected 0)
myeckeyp521.pub: PUBLIC KEY INFO
myeckeyp521.p8: PKCS8 ENCRYPTED PRIVATE KEY

```

[[Contents](#topofpage)] [[Index](#index)]

<a id="ECC_PublicKeyFromPrivate"></a>ECC_PublicKeyFromPrivate
-------------------------------------------------------------

Converts an internal EC private key string into an internal EC public key string.

### VBA/VB6 Syntax

`Public Declare Function ECC_PublicKeyFromPrivate Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strIntKeyString As String, ByVal nOptions As Long) As Long`

`nRet = ECC_PublicKeyFromPrivate(strOutput, nOutChars, strIntKeyString, nOptions)`

### C/C++ Syntax

`long __stdcall ECC_PublicKeyFromPrivate(char *szOutput, long nOutChars, const char *szIntKeyString, long nOptions);`

### Parameters

*szOutput*
:   [out] string of sufficient length to receive the output.

*nOutChars*
:   [in]  specifying the maximum number of characters to be received.

*szIntKeyString*
:   [in] containing the private key as an internal key string.

*nOptions*
:   [in] not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a nonzero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`eccPublicKeyFromPrivate`](#VB_eccPublicKeyFromPrivate) (szIntKeyString As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Ecc.PublicKeyFromPrivate Method](#M_Ecc_PublicKeyFromPrivate) 

### C++ (STL) Equivalent

static std::string [dipki::Ecc::PublicKeyFromPrivate](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#a71a6adfb1db7101969d7b625b9d8d842 "External link") (std::string internalKey)

### Python Equivalent

static [Ecc.publickey_from_private](https://cryptosys.net/pki/pydocpki/class-stubs/Ecc.html#cryptosyspki.Ecc.publickey_from_private "External link")(intkeystr)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

Use this to derive the public key from the EC private key, where both values are represented as "internal" key strings. 

### Example (VBA core function)

```

Dim nRet As Long
Dim nChars As Long
Dim strIntPriKey As String
Dim strIntPubKey As String
Dim strKeyFile As String
Dim strNewKeyFile As String
Dim strPassword As String
Dim strTypeName As String
Dim strFileName As String

strKeyFile = "myeckeyp521.p8"
strPassword = "password"

' 1. READ IN THE PRIVATE KEY: int_string <- file
Debug.Print "FILE: " & strKeyFile
' Find required length of internal key string
nChars = ECC_ReadPrivateKey("", 0, strKeyFile, strPassword, 0)
Debug.Print "ECC_ReadPrivateKey returns " & nChars & " (expected +ve)"
If (nChars <= 0) Then Exit Sub   ' CATCH ERROR HERE
' Dimension the string to receive output
strIntPriKey = String(nChars, " ")
' Read into internal key string
nChars = ECC_ReadPrivateKey(strIntPriKey, Len(strIntPriKey), strKeyFile, strPassword, 0)
Debug.Print "[" & strIntPriKey & "]"

' 2. CONVERT TO PUBLIC: int_string <-- int_string
nChars = ECC_PublicKeyFromPrivate("", 0, strIntPriKey, 0)
Debug.Print "ECC_PublicKeyFromPrivate returns " & nChars & " (expected +ve)"
If (nChars <= 0) Then Exit Sub   ' CATCH ERROR HERE
strIntPubKey = String(nChars, " ")
nChars = ECC_PublicKeyFromPrivate(strIntPubKey, Len(strIntPubKey), strIntPriKey, 0)
Debug.Print "[" & strIntPubKey & "]"
      
' 3. SAVE AS NEW PUBLIC KEY FILE: file <-- int_string
strNewKeyFile = "myeckeyp521_new.pub"
nRet = ECC_SaveKey(strNewKeyFile, strIntPubKey, 0)
Debug.Print "ECC_SaveKey returns " & nRet & " (expected 0)"

' Check the type of file we made
strTypeName = String(PKI_ASN1_TYPE_MAXCHARS, " ")
strFileName = strNewKeyFile
nChars = ASN1_Type(strTypeName, Len(strTypeName), strFileName, 0)
If nChars > 0 Then Debug.Print strFileName & ": " & Left(strTypeName, nChars)

```

```

FILE: myeckeyp521.p8
ECC_ReadPrivateKey returns 336 (expected +ve)
[PVECRDe...PmEAIGm5Uj1HI=]
ECC_PublicKeyFromPrivate returns 212 (expected +ve)
[MIGbMBA...sxHXznms=]
ECC_SaveKey returns 0 (expected 0)
myeckeyp521_new.pub: PUBLIC KEY INFO

```

### Example (VBA wrapper function)

```

Dim strIntKey As String

' Read in public key from file
strIntKey = eccReadPublicKey("myeckeyp256.pub")
Debug.Assert Len(strIntKey) > 0
Debug.Print "Key curve=" & eccQueryKey(strIntKey, "curveName", 0) & " keyBits=" & _
    eccQueryKey(strIntKey, "keyBits", 0) & _
    " and is a " & _
    IIf(eccQueryKey(strIntKey, "isPrivate") = "1", "Private", "Public") & " key"
Debug.Print eccQueryKey(strIntKey, "publicKey")
Debug.Print "KeyHashCode=0x" & Hex(ECC_KeyHashCode(strIntKey))

' Read in private key from file
strIntKey = eccReadPrivateKey("myeckeyp256.p8", "password")
Debug.Assert Len(strIntKey) > 0
Debug.Print "Key curve=" & eccQueryKey(strIntKey, "curveName", 0) & " keyBits=" & _
    eccQueryKey(strIntKey, "keyBits", 0) & _
    " and is a " & _
    IIf(eccQueryKey(strIntKey, "isPrivate") = "1", "Private", "Public") & " key"
Debug.Print eccQueryKey(strIntKey, "publicKey")
Debug.Print "KeyHashCode=0x" & Hex(ECC_KeyHashCode(strIntKey))

' Derive public key from private key
strIntKey = eccPublicKeyFromPrivate(strIntKey)
Debug.Assert Len(strIntKey) > 0
Debug.Print "Key curve=" & eccQueryKey(strIntKey, "curveName", 0) & " keyBits=" & _
    eccQueryKey(strIntKey, "keyBits", 0) & _
    " and is a " & _
    IIf(eccQueryKey(strIntKey, "isPrivate") = "1", "Private", "Public") & " key"
Debug.Print eccQueryKey(strIntKey, "publicKey")
Debug.Print "KeyHashCode=0x" & Hex(ECC_KeyHashCode(strIntKey))
```

### See Also

[ECC_ReadPrivateKey](#ECC_ReadPrivateKey)
[ECC_ReadPublicKey](#ECC_ReadPublicKey)

[[Contents](#topofpage)] [[Index](#index)]

<a id="ECC_QueryKey"></a>ECC_QueryKey
-------------------------------------

Queries an EC key string for selected information.

### VBA/VB6 Syntax

`Public Declare Function ECC_QueryKey Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strIntKeyString As String, ByVal strQuery As String, ByVal nOptions As Long) As Long`

`nRet = ECC_QueryKey(strOutput, Len(strOutput), strIntKeyString, strQuery, nOptions)`

### C/C++ Syntax

`long __stdcall ECC_QueryKey(char *szOutput, long nOutChars, const char *szIntKeyString, const char *szQuery, long nOptions);`

### Parameters

*szOutput*
:   [out] string of sufficient length to receive the output.

*nOutChars*
:   [in]  specifying the maximum number of characters to be received.

*szIntKeyString*
:   [in] containing the key as an internal key string.

*szQuery*
:   [in] specifying the query (see Remarks below).

*nOptions*
:   [in] not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is a positive integer indicating either the result itself (if the result is a number) 
or the number of characters in the output string (if the query is looking for a string). 
If the item queried cannot be found, the return value is zero. 
If there is an error (e.g. invalid input), it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`eccQueryKey`](#VB_eccQueryKey) (szIntKeyString As String, szQuery As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Ecc.QueryKey Method](#M_Ecc_QueryKey) 

### C++ (STL) Equivalent

static std::string [dipki::Ecc::QueryKey](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#abe2d746ed26a73dc4404f59b96df7fd6 "External link") (std::string internalKey, std::string query)

### Python Equivalent

static [Ecc.query_key](https://cryptosys.net/pki/pydocpki/class-stubs/Ecc.html#cryptosyspki.Ecc.query_key "External link")(intkeystr, query)

### Remarks

Valid queries are (case-insensitive):

| Query String | Returns | Data Type |
| --- | --- | --- |
| `curveName` | Name of the curve | String |
| `keyBits` | Number of bits in the key | Number |
| `isPrivate` | 1 if the key is a private key; 0 if not | Number |
| `isValid` | 1 if the key is valid; 0 if not | Number |
| `privateKey` | Value of the private key in hex format | String |
| `publicKey` | Value of the public key in hex format | String |

The "raw" VBA/C function behaves differently depending on whether the output is a string or a number. 
If the result data type is a number then it returns the value directly.
If the result is a string, then it sets *szOutput* and returns the number of characters in the string.
The required number of characters can be found by passing zero for *nOutChars* or a null string for *szOutput*.
ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

Note that the VBA wrapper function and the C#/`VB.NET` methods *always* return a string, which is different from the behaviour of the raw VB6/C function.

### Example (VBA core function)

```

Dim nRet As Long
Dim nChars As Long
Dim strIntKey As String
Dim strKeyFile As String
Dim strQuery As String
Dim strBuffer As String
Dim strPassword As String

strKeyFile = "myeckeyp256.p8"
strPassword = "password"

Debug.Print "FILE: " & strKeyFile
' Find required length of internal key string
nChars = ECC_ReadPrivateKey("", 0, strKeyFile, strPassword, 0)
Debug.Print "ECC_ReadPrivateKey returns " & nChars & " (expected +ve)"
' Dimension the string to receive output
strIntKey = String(nChars, " ")
' Read into an ephemeral internal key string
nChars = ECC_ReadPrivateKey(strIntKey, Len(strIntKey), strKeyFile, strPassword, 0)
' Find the curve name (output as a string)
strBuffer = String(32, " ")
strQuery = "curveName"
nChars = ECC_QueryKey(strBuffer, Len(strBuffer), strIntKey, strQuery, 0)
If nChars > 0 Then Debug.Print "ECC_QueryKey('" & strQuery & "')=[" & Left(strBuffer, nChars) & "]"
' Find the key size in bits (NB returned directly)
strQuery = "keyBits"
nRet = ECC_QueryKey("", 0, strIntKey, strQuery, 0)
Debug.Print "ECC_QueryKey('" & strQuery & "')=" & nRet & " (expected +ve)"
' Is it a private or public key?
strQuery = "isPrivate"
nRet = ECC_QueryKey("", 0, strIntKey, strQuery, 0)
Debug.Print "ECC_QueryKey('" & strQuery & "')=" & nRet & " (expected 1 = True)"
' Extract the private key in hex form
strQuery = "privateKey"
' Get required length of output string
nChars = ECC_QueryKey("", 0, strIntKey, strQuery, 0)
strBuffer = String(nChars, " ")
nChars = ECC_QueryKey(strBuffer, Len(strBuffer), strIntKey, strQuery, 0)
Debug.Print "ECC_QueryKey('" & strQuery & "')="
If nChars > 0 Then Debug.Print "[" & Left(strBuffer, nChars) & "]"
' Extract the public key in hex form
strQuery = "publicKey"
nChars = ECC_QueryKey("", 0, strIntKey, strQuery, 0)
strBuffer = String(nChars, " ")
nChars = ECC_QueryKey(strBuffer, Len(strBuffer), strIntKey, strQuery, 0)
Debug.Print "ECC_QueryKey('" & strQuery & "')="
If nChars > 0 Then Debug.Print "[" & Left(strBuffer, nChars) & "]"

```

```

FILE: myeckeyp256.p8
ECC_ReadPrivateKey returns 100 (expected +ve)
ECC_QueryKey('curveName')=[secp256r1]
ECC_QueryKey('keyBits')=256 (expected +ve)
ECC_QueryKey('isPrivate')=1 (expected 1 = True)
ECC_QueryKey('privateKey')=
[0955cc9904330205fa00559dbcae5c978c42a2f96fc1d661b66f617331ef0738]
ECC_QueryKey('publicKey')=
[0403af975e940d6db5184576a81fe50914579c7d777bfc70725b24505e03e49a9e004025069f3e8981d45027c953d57818a2b212ec7d1bfcfac0ea645dff81ed6b]

```

### Example (VBA wrapper function)

```

Dim curveName As String
Dim alicePrivateKeyHex As String
Dim ourPrivateKey As String

curveName = "X25519"
alicePrivateKeyHex = "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a"

ourPrivateKey = eccReadKeyByCurve(alicePrivateKeyHex, curveName, PKI_ECC_PRIVATE_KEY)
Debug.Assert Len(ourPrivateKey) > 0
Debug.Print "Key curve=" & eccQueryKey(ourPrivateKey, "curveName", 0) & " keyBits=" & eccQueryKey(ourPrivateKey, "keyBits", 0)

```

### See Also

[ECC_ReadPrivateKey](#ECC_ReadPrivateKey)
[ECC_ReadPublicKey](#ECC_ReadPublicKey)

[[Contents](#topofpage)] [[Index](#index)]

<a id="ECC_ReadKeyByCurve"></a>ECC_ReadKeyByCurve
-------------------------------------------------

Reads an EC key from its hexadecimal (base16) representation.

### VBA/VB6 Syntax

`Public Declare Function ECC_ReadKeyByCurve Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strHexKey As String, ByVal strCurveName As String, ByVal nOptions As Long) As Long`

`nRet = ECC_ReadKeyByCurve(strOutput, Len(strOutput), strHexKey, strCurveName, nOptions)`

### C/C++ Syntax

`long __stdcall ECC_ReadKeyByCurve(char *szOutput, long nOutChars, const char *szHexKey, const char *szCurveName, long nOptions);`

### Parameters

*szOutput*
:   [out] string of sufficient length to receive the output.

*nOutChars*
:   [in]  specifying the maximum number of characters to be received.

*szHexKey*
:   [in] containing a hexadecimal (base16) representation of the key

*szCurveName*
:   [in] containing the name of the elliptic curve (see remarks)

*nOptions*
:   [in] For **Safe Curves**
specify `PKI_ECC_PRIVATE_KEY` or `PKI_ECC_PUBLIC_KEY` to indicate that the key value represents a private or public key, respectively.
Otherwise, *nOptions* is ignored.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a nonzero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`eccReadKeyByCurve`](#VB_eccReadKeyByCurve) (szHexKey As String, szCurveName As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Ecc.ReadKeyByCurve Method](#M_Ecc_ReadKeyByCurve) 

### C++ (STL) Equivalent

static std::string [dipki::Ecc::ReadKeyByCurve](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#a9201fbe6d4b6b5a45c47b3865253ce7e "External link") (std::string hexKey, Curve curve, Publicity publicity=Publicity::PrivateKey)

### Python Equivalent

static [Ecc.read_key_by_curve](https://cryptosys.net/pki/pydocpki/class-stubs/Ecc.html#cryptosyspki.Ecc.read_key_by_curve "External link")(keyhex, curvename, ispublic=False)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The output string is an ephemeral internal key string valid only for the current session.
This internal key string can be used directly by functions such as [ECC_DHSharedSecret](#ECC_DHSharedSecret) or [SIG_SignData](#SIG_SignData).
You can analyze the key string using [ECC_QueryKey](#ECC_QueryKey) or save it in one of the supported key file formats 
using [ECC_SaveKey](#ECC_SaveKey) or [ECC_SaveEncKey](#ECC_SaveEncKey).
The input string is expected to be the hexadecimal (base16) representation of a private or public key.

**NIST/SEC/Brainpool curves:** A private key is represented by the hexadecimal encoding of its integer value encoded in octets
as per section 3 of [[RFC5915](#RFC5915)].
A public key is represented by the hexadecimal encoding of the octet string as defined in section 4.3.6 of
[[X9-63](#X9-63)]; that is, `04||Px||Py`.

Only the uncompressed form of a public key (beginning "04") is supported due to patent issues.
It is an error if the key value is out of range or not a valid point on the curve.

**Safe curves:** Both private and public keys are represented by the hexadecimal encoding of its integer value 
encoded as a byte array in *little-endian* form as per [[RFC7748](#RFC7748)] and [[RFC8032](#RFC8032)]. 
For Ed25519 and X25519, the input string *szHexKey* is always expected to be a hexadecimal representation of exactly 32 bytes.
Set *nOptions* as `PKI_ECC_PRIVATE_KEY` (default 0) or `PKI_ECC_PUBLIC_KEY` to indicate whether the key value represents a private or public key, respectively.
Any 32-byte key string will be accepted as input and any required bit masking (e.g. for an X25519 private key) will be applied before use.

Supported curve names for *szCurveName* are: 

| Curve name | Alternative names | Remarks |
| --- | --- | --- |
| `secp192r1` | `P-192`, `P_192`, `prime192v1` | NIST |
| `secp224r1` | `P-224`, `P_224` | NIST |
| `secp256r1` | `P-256`, `P_256`, `prime256v1` | NIST |
| `secp384r1` | `P-384`, `P_384` | NIST |
| `secp521r1` | `P-521`, `P_521` | NIST |
| `secp256k1` |  | SEC/Bitcoin |
| `Ed25519` |  | Safe EdDSA curve [RFC8032] |
| `Ed448` |  | Safe EdDSA curve [RFC8032] |
| `X25519` |  | Safe ECDH curve [RFC7748] |
| `X448` |  | Safe ECDH curve [RFC7748] |
| `brainpoolP256r1` |  | [RFC5639] |
| `brainpoolP384r1` |  | [RFC5639] |
| `brainpoolP512r1` |  | [RFC5639] |

### Example (VBA core function)

```

Dim nRet As Long
Dim nChars As Long
Dim strIntKey As String
Dim strHexKey As String
Dim strCurveName As String
Dim strQuery As String
Dim strBuffer As String
Dim strBase58 As String
Dim abTemp() As Byte
Dim nBytes As Long
  
' 1. A NIST P-192 public key in X9.63 uncompressed format
strHexKey = _
 "0496C248BE456192FA1380CCF615D171452F41FF31B92BA733524FD77168DEA4425A3EA8FD79B98DC7AFE83C86DCC39A96"
strCurveName = "prime192v1"  ' A synonym for "P-192"
Debug.Print "KEYHEX: " & strHexKey
Debug.Print "CURVE: " & strCurveName
' Find required length of internal key string
nChars = ECC_ReadKeyByCurve("", 0, strHexKey, strCurveName, 0)
Debug.Print "ECC_ReadKeyByCurve returns " & nChars & " (expected +ve)"
' Dimension the string to receive output
strIntKey = String(nChars, " ")
' Read into internal key string
nChars = ECC_ReadKeyByCurve(strIntKey, Len(strIntKey), strHexKey, strCurveName, 0)
' Find the key size in bits
strQuery = "keyBits"
nRet = ECC_QueryKey("", 0, strIntKey, strQuery, 0)
Debug.Print "ECC_QueryKey('" & strQuery & "')=" & nRet & " (expected +ve)"
' Is it a private or public key?
strQuery = "isPrivate"
nRet = ECC_QueryKey("", 0, strIntKey, strQuery, 0)
Debug.Print "ECC_QueryKey('" & strQuery & "')=" & nRet & " (expected 0)"
Debug.Print

' 2. A Bitcoin private key in base58 form
strBase58 = "6ACCbmy9qwiFcuVgvxNNwMPfoghobzznWrLs3v7t3RmN"
Debug.Print "KEYB58: " & strBase58
strCurveName = "secp256k1"
' Convert to a hex string
nBytes = CNV_Base58ToBytes(0, 0, strBase58)
Debug.Assert (nBytes > 0)
ReDim abTemp(nBytes - 1)
nBytes = CNV_Base58ToBytes(abTemp(0), nBytes, strBase58)
strHexKey = cnvHexStrFromBytes(abTemp)
Debug.Print "KEYHEX: " & strHexKey
Debug.Print "CURVE: " & strCurveName
' Find required length of internal key string
nChars = ECC_ReadKeyByCurve("", 0, strHexKey, strCurveName, 0)
Debug.Print "ECC_ReadKeyByCurve returns " & nChars & " (expected +ve)"
' Dimension the string to receive output
strIntKey = String(nChars, " ")
' Read into internal key string
nChars = ECC_ReadKeyByCurve(strIntKey, Len(strIntKey), strHexKey, strCurveName, 0)
' Find the key size in bits
strQuery = "keyBits"
nRet = ECC_QueryKey("", 0, strIntKey, strQuery, 0)
Debug.Print "ECC_QueryKey('" & strQuery & "')=" & nRet & " (expected +ve)"
' Is it a private or public key?
strQuery = "isPrivate"
nRet = ECC_QueryKey("", 0, strIntKey, strQuery, 0)
Debug.Print "ECC_QueryKey('" & strQuery & "')=" & nRet & " (expected 1)"

' Extract the public key in hex form
strQuery = "publicKey"
nChars = ECC_QueryKey("", 0, strIntKey, strQuery, 0)
strBuffer = String(nChars, " ")
nChars = ECC_QueryKey(strBuffer, Len(strBuffer), strIntKey, strQuery, 0)
Debug.Print "ECC_QueryKey('" & strQuery & "')="
If nChars > 0 Then Debug.Print "[" & Left(strBuffer, nChars) & "]"

```

```

KEYHEX: 0496C248BE456192FA1380CCF615D171452F41FF31B92BA733524FD77168DEA4425A3EA8FD79B98DC7AFE83C86DCC39A96
CURVE: prime192v1
ECC_ReadKeyByCurve returns 100 (expected +ve)
ECC_QueryKey('keyBits')=192 (expected +ve)
ECC_QueryKey('isPrivate')=0 (expected 0)

KEYB58: 6ACCbmy9qwiFcuVgvxNNwMPfoghobzznWrLs3v7t3RmN
KEYHEX: 4CA55366ADE9E9BC12319DFFC246F64EB7FA07755925B92CEFC92D740DBC51ED
CURVE: secp256k1
ECC_ReadKeyByCurve returns 196 (expected +ve)
ECC_QueryKey('keyBits')=256 (expected +ve)
ECC_QueryKey('isPrivate')=1 (expected 1)
ECC_QueryKey('publicKey')=
[04654bacc2fc7a3bde0f8eb95dc5aac9ba1df732255cf7f2eb7e1e8e6edbb1f4188ff3752ac4bdf1e3a31a488747745dddcbabd33a10c3b52d737c092851da13c0]

```

### Example (VBA wrapper function)

```

Dim curveName As String
Dim alicePrivateKeyHex As String
Dim ourPrivateKey As String
Dim nChars As Long

curveName = "X25519"
alicePrivateKeyHex = "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a"

' The old long way...
nChars = ECC_ReadKeyByCurve(vbNullString, 0, alicePrivateKeyHex, curveName, PKI_ECC_PRIVATE_KEY)
Debug.Assert nChars > 0
ourPrivateKey = String(nChars, " ")
nChars = ECC_ReadKeyByCurve(ourPrivateKey, nChars, alicePrivateKeyHex, curveName, PKI_ECC_PRIVATE_KEY)

' The new short way with a wrapper function
ourPrivateKey = eccReadKeyByCurve(alicePrivateKeyHex, curveName, PKI_ECC_PRIVATE_KEY)
Debug.Assert Len(ourPrivateKey) > 0
Debug.Print "Key curve=" & eccQueryKey(ourPrivateKey, "curveName", 0) & " keyBits=" & eccQueryKey(ourPrivateKey, "keyBits", 0)

```

```

Dim strCurveName As String
Dim ourPrivateKey As String
Dim theirPublicKey As String
Dim lpZZ() As Byte

' Ref: RFC7748 Section 6.1
Const alicePrivateKeyHex As String = "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a"
Const alicePublicKeyHex As String = "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a"
Const bobPrivateKeyHex As String = "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb"
Const bobPublicKeyHex As String = "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f"

strCurveName = "X25519"
' 1. Alice's private + Bob's public
ourPrivateKey = eccReadKeyByCurve(alicePrivateKeyHex, strCurveName, PKI_ECC_PRIVATE_KEY)
Debug.Print "Our key has " & eccQueryKey(ourPrivateKey, "keyBits") & " bits and is a " & _
    IIf(eccQueryKey(ourPrivateKey, "isPrivate") = "1", "Private", "Public") & " key"
theirPublicKey = eccReadKeyByCurve(bobPublicKeyHex, strCurveName, PKI_ECC_PUBLIC_KEY)
Debug.Print "Their key has " & eccQueryKey(theirPublicKey, "keyBits") & " bits and is a " & _
    IIf(eccQueryKey(theirPublicKey, "isPrivate") = "1", "Private", "Public") & " key"
' Compute shared secret
lpZZ = eccDHSharedSecret(ourPrivateKey, theirPublicKey)
Debug.Print "ZZ=" & cnvHexStrFromBytes(lpZZ)
Debug.Print "OK=4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"

' 2. Bob's private + Alice's public
ourPrivateKey = eccReadKeyByCurve(bobPrivateKeyHex, strCurveName, PKI_ECC_PRIVATE_KEY)
Debug.Print "Our key has " & eccQueryKey(ourPrivateKey, "keyBits") & " bits and is a " & _
    IIf(eccQueryKey(ourPrivateKey, "isPrivate") = "1", "Private", "Public") & " key"
theirPublicKey = eccReadKeyByCurve(alicePublicKeyHex, strCurveName, PKI_ECC_PUBLIC_KEY)
Debug.Print "Their key has " & eccQueryKey(theirPublicKey, "keyBits") & " bits and is a " & _
    IIf(eccQueryKey(theirPublicKey, "isPrivate") = "1", "Private", "Public") & " key"
' Compute shared secret
lpZZ = eccDHSharedSecret(ourPrivateKey, theirPublicKey)
Debug.Print "ZZ=" & cnvHexStrFromBytes(lpZZ)
Debug.Print "OK=4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"
```

### See Also

[ECC_QueryKey](#ECC_QueryKey)

[[Contents](#topofpage)] [[Index](#index)]

<a id="ECC_ReadPrivateKey"></a>ECC_ReadPrivateKey
-------------------------------------------------

Reads an EC private key from a file into an internal key string.

### VBA/VB6 Syntax

`Public Declare Function ECC_ReadPrivateKey Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strKeyFileOrString As String, ByVal strPassword As String, ByVal nOptions As Long) As Long`

`nRet = ECC_ReadPrivateKey(strOutput, Len(strOutput), strKeyFileOrString, strPassword, nOptions)`

### C/C++ Syntax

`long __stdcall ECC_ReadPrivateKey(char *szOutput, long nOutChars, const char *szKeyFileOrString, const char *szPassword, long nOptions);`

### Parameters

*szOutput*
:   [out] string of sufficient length to receive the output.

*nOutChars*
:   [in]  specifying the maximum number of characters to be received.

*szKeyFileOrString*
:   [in] specifying either the name of file containing the key 
	or a string containing the key in [PEM format](#pemstring).

*szPassword*
:   [in] password for the key file, if encrypted; otherwise set as `""`.

*nOptions*
:   [in] not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a nonzero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`eccReadPrivateKey`](#VB_eccReadPrivateKey) (szKeyFileOrString As String, Optional szPassword As String = "", Optional nOptions As Long = 0) As String

### .NET Equivalent

[Ecc.ReadPrivateKey Method](#M_Ecc_ReadPrivateKey) 

### C++ (STL) Equivalent

static std::string [dipki::Ecc::ReadPrivateKey](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#a7ab4058c743e56c7e14ecd7812cd8173 "External link") (std::string keyFileOrString, std::string password="")

### Python Equivalent

static [Ecc.read_private_key](https://cryptosys.net/pki/pydocpki/class-stubs/Ecc.html#cryptosyspki.Ecc.read_private_key "External link")(keyfileorstr, password="")

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

This reads both encrypted private keys and the unencrypted PKCS#8 PrivateKeyInfo and ECPrivateKey formats.
Set *szPassword* as the empty string `""` if not required.

### Example (VBA core function)

```

Dim nRet As Long
Dim nChars As Long
Dim strIntKey As String
Dim strKeyFile As String
Dim strPassword As String
Dim strNewKeyFile As String
Dim strTypeName As String
Dim strFileName As String

strKeyFile = "myeckeyp256.p8"
strPassword = "password"

' Find required length of internal key string
nChars = ECC_ReadPrivateKey("", 0, strKeyFile, strPassword, 0)
Debug.Print "ECC_ReadPrivateKey returns " & nChars & " (expected +ve)"
' Dimension the string to receive output
strIntKey = String(nChars, " ")
' Read it in
nChars = ECC_ReadPrivateKey(strIntKey, Len(strIntKey), strKeyFile, strPassword, 0)
' Caution: internal key string is only valid for the current session
Debug.Print "[" & strIntKey & "]"

' Now save in a different format: ECPrivatekey in PEM encoding
strNewKeyFile = "myeckey.pem"
nRet = ECC_SaveKey(strNewKeyFile, strIntKey, PKI_KEY_FORMAT_PEM)
Debug.Print "ECC_SaveKey returns " & nRet & " (expected 0)"

' Check the types of file we made
strTypeName = String(PKI_ASN1_TYPE_MAXCHARS, " ")
strFileName = strNewKeyFile
nChars = ASN1_Type(strTypeName, Len(strTypeName), strFileName, 0)
If nChars > 0 Then Debug.Print strFileName & ": " & Left(strTypeName, nChars)

```

```

ECC_ReadPrivateKey returns 100 (expected +ve)
[PVECwcBFxO1TkZ3D/O6...nNWDXV9xuIUuVZqCO5]
ECC_SaveKey returns 0 (expected 0)
myeckey.pem: EC PRIVATE KEY

```

The output file should look similar to the following:

```

-----BEGIN EC PRIVATE KEY-----
MDECAQEEIAlVzJkEMwIF+gBVnbyuXJeMQqL5b8HWYbZvYXMx7wc4oAoGCCqGSM49
AwEH
-----END EC PRIVATE KEY-----

```

### Example (VBA wrapper function)

```

Dim strIntKey As String

' Read in public key from file
strIntKey = eccReadPublicKey("myeckeyp256.pub")
Debug.Assert Len(strIntKey) > 0
Debug.Print "Key curve=" & eccQueryKey(strIntKey, "curveName", 0) & " keyBits=" & _
    eccQueryKey(strIntKey, "keyBits", 0) & _
    " and is a " & _
    IIf(eccQueryKey(strIntKey, "isPrivate") = "1", "Private", "Public") & " key"
Debug.Print eccQueryKey(strIntKey, "publicKey")
Debug.Print "KeyHashCode=0x" & Hex(ECC_KeyHashCode(strIntKey))

' Read in private key from file
strIntKey = eccReadPrivateKey("myeckeyp256.p8", "password")
Debug.Assert Len(strIntKey) > 0
Debug.Print "Key curve=" & eccQueryKey(strIntKey, "curveName", 0) & " keyBits=" & _
    eccQueryKey(strIntKey, "keyBits", 0) & _
    " and is a " & _
    IIf(eccQueryKey(strIntKey, "isPrivate") = "1", "Private", "Public") & " key"
Debug.Print eccQueryKey(strIntKey, "publicKey")
Debug.Print "KeyHashCode=0x" & Hex(ECC_KeyHashCode(strIntKey))

' Derive public key from private key
strIntKey = eccPublicKeyFromPrivate(strIntKey)
Debug.Assert Len(strIntKey) > 0
Debug.Print "Key curve=" & eccQueryKey(strIntKey, "curveName", 0) & " keyBits=" & _
    eccQueryKey(strIntKey, "keyBits", 0) & _
    " and is a " & _
    IIf(eccQueryKey(strIntKey, "isPrivate") = "1", "Private", "Public") & " key"
Debug.Print eccQueryKey(strIntKey, "publicKey")
Debug.Print "KeyHashCode=0x" & Hex(ECC_KeyHashCode(strIntKey))
```

### See Also

[ECC_ReadPublicKey](#ECC_ReadPublicKey)
[ECC_QueryKey](#ECC_QueryKey)

[[Contents](#topofpage)] [[Index](#index)]

<a id="ECC_ReadPublicKey"></a>ECC_ReadPublicKey
-----------------------------------------------

Reads an EC public key from a file into an internal key string.

### VBA/VB6 Syntax

`Public Declare Function ECC_ReadPublicKey Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strKeyFileOrString As String, ByVal nOptions As Long) As Long`

`nRet = ECC_ReadPublicKey(strOutput, Len(strOutput), strKeyFileOrString, nOptions)`

### C/C++ Syntax

`long __stdcall ECC_ReadPublicKey(char *szOutput, long nOutChars, const char *szKeyFileOrString, long nOptions);`

### Parameters

*szOutput*
:   [out] string of sufficient length to receive the output.

*nOutChars*
:   [in]  specifying the maximum number of characters to be received.

*szKeyFileOrString*
:   [in] specifying either the name of file containing the key 
	or a string containing the key in [PEM format](#pemstring).

*nOptions*
:   [in] not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`eccReadPublicKey`](#VB_eccReadPublicKey) (szKeyFileOrString As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Ecc.ReadPublicKey Method](#M_Ecc_ReadPublicKey) 

### C++ (STL) Equivalent

static std::string [dipki::Ecc::ReadPublicKey](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#af296521d6be949c86bb388db37750c99 "External link") (std::string keyFileOrString)

### Python Equivalent

static [Ecc.read_public_key](https://cryptosys.net/pki/pydocpki/class-stubs/Ecc.html#cryptosyspki.Ecc.read_public_key "External link")(keyfileorstr)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

*[New in v12.0]* An EC public key can also be read directly from an X.509 certificate (or its [base64 representation](#base64forcert)).

### Example (VBA core function)

```

Dim nRet As Long
Dim nChars As Long
Dim strIntKey As String
Dim strKeyFile As String
Dim strQuery As String

strKeyFile = "myeckeyp521.pub"

Debug.Print "FILE: " & strKeyFile
' Find required length of internal key string
nChars = ECC_ReadPublicKey("", 0, strKeyFile, 0)
Debug.Print "ECC_ReadPublicKey returns " & nChars & " (expected +ve)"
' Dimension the string to receive output
strIntKey = String(nChars, " ")
' Read into internal key string
nChars = ECC_ReadPublicKey(strIntKey, Len(strIntKey), strKeyFile, 0)
Debug.Print "[" & strIntKey & "]"
' Find the key size in bits (NB returned directly)
strQuery = "keyBits"
nRet = ECC_QueryKey("", 0, strIntKey, strQuery, 0)
Debug.Print "ECC_QueryKey('" & strQuery & "')=" & nRet & " (expected +ve)"
' Is it a private or public key?
strQuery = "isPrivate"
nRet = ECC_QueryKey("", 0, strIntKey, strQuery, 0)
Debug.Print "ECC_QueryKey('" & strQuery & "')=" & nRet & " (expected 0)"

```

```

FILE: myeckeyp521.pub
ECC_ReadPublicKey returns 212 (expected +ve)
[MIGbMBAGByqGSM49AgEGBSuB ... NARus1tKwwWhEJGs=]
ECC_QueryKey('keyBits')=521 (expected +ve)
ECC_QueryKey('isPrivate')=0 (expected 0)

```

### Example (VBA wrapper function)

```

Dim strIntKey As String

' Read in public key from file
strIntKey = eccReadPublicKey("myeckeyp256.pub")
Debug.Assert Len(strIntKey) > 0
Debug.Print "Key curve=" & eccQueryKey(strIntKey, "curveName", 0) & " keyBits=" & _
    eccQueryKey(strIntKey, "keyBits", 0) & _
    " and is a " & _
    IIf(eccQueryKey(strIntKey, "isPrivate") = "1", "Private", "Public") & " key"
Debug.Print eccQueryKey(strIntKey, "publicKey")
Debug.Print "KeyHashCode=0x" & Hex(ECC_KeyHashCode(strIntKey))

' Read in private key from file
strIntKey = eccReadPrivateKey("myeckeyp256.p8", "password")
Debug.Assert Len(strIntKey) > 0
Debug.Print "Key curve=" & eccQueryKey(strIntKey, "curveName", 0) & " keyBits=" & _
    eccQueryKey(strIntKey, "keyBits", 0) & _
    " and is a " & _
    IIf(eccQueryKey(strIntKey, "isPrivate") = "1", "Private", "Public") & " key"
Debug.Print eccQueryKey(strIntKey, "publicKey")
Debug.Print "KeyHashCode=0x" & Hex(ECC_KeyHashCode(strIntKey))

' Derive public key from private key
strIntKey = eccPublicKeyFromPrivate(strIntKey)
Debug.Assert Len(strIntKey) > 0
Debug.Print "Key curve=" & eccQueryKey(strIntKey, "curveName", 0) & " keyBits=" & _
    eccQueryKey(strIntKey, "keyBits", 0) & _
    " and is a " & _
    IIf(eccQueryKey(strIntKey, "isPrivate") = "1", "Private", "Public") & " key"
Debug.Print eccQueryKey(strIntKey, "publicKey")
Debug.Print "KeyHashCode=0x" & Hex(ECC_KeyHashCode(strIntKey))
```

### See Also

[ECC_ReadPrivateKey](#ECC_ReadPrivateKey)
[ECC_QueryKey](#ECC_QueryKey)

[[Contents](#topofpage)] [[Index](#index)]

<a id="ECC_SaveEncKey"></a>ECC_SaveEncKey
-----------------------------------------

Saves an internal EC private key string to an encrypted private key file.

### VBA/VB6 Syntax

`Public Declare Function ECC_SaveEncKey Lib "diCrPKI.dll" (ByVal strFileOut As String, ByVal strIntKeyString As String, ByVal strPassword As String, ByVal strParams As String, ByVal nOptions As Long) As Long`

`nRet = ECC_SaveEncKey(strFileOut, strIntKeyString, strPassword, strParams, nOptions)`

### C/C++ Syntax

`long __stdcall ECC_SaveEncKey(const char *szFileOut, const char *szIntKeyString, const char *szPassword, const char *szParams, long nOptions);`

### Parameters

*szFileOut*
:   [in] name of key file to be created.

*szIntKeyString*
:   [in] the private key in an internal key string.

*szPassword*
:   [in] the password to be used for the encrypted key file

*szParams*
:   [in] (optional) parameters. Set as the empty string `""` for defaults.
	Otherwise include a set of attribute-value pairs separated by a semi-colon ";" to set options from the following
* `count=<nnn>` to set the iteration count used in the PBKDF method,
	e.g. `"count=5000;"` [default=`2048`]
* `prf=<hmac-name>` to change the HMAC algorithm used in the PBKDF2 method,
	e.g. `"prf=hmacWithSHA256;"` [default=`hmacwithSHA1`]

*nOptions*
:   [in] containing a flag to indicate the algorithm to be used 
to encrypt the private key file. Select from:  

`PKI_PBE_SHA_3DES` (0) for `"pbeWithSHAAnd3-KeyTripleDES-CBC"` (default)  

`PKI_PBE_PBKDF2_DESEDE3` for PBKDF2 using `des-EDE3-CBC`  

`PKI_PBE_PBKDF2_AES128` for PBKDF2 using `aes128-CBC`  

`PKI_PBE_PBKDF2_AES192` for PBKDF2 using `aes192-CBC`  

`PKI_PBE_PBKDF2_AES256` for PBKDF2 using `aes256-CBC`  

(there are more options - see [security options for encrypted private keys](#encryptedkeyoptions))  

and optionally add  

`PKI_KEY_FORMAT_PEM` to save the key files in PEM form (default is binary DER-encoded format).

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`eccSaveEncKey`](#VB_eccSaveEncKey) (szOutputFile As String, szKeyStr As String, szPassword As String, Optional szParams As String = "", Optional nOptions As Long = 0) As Long

### .NET Equivalent

[Ecc.SaveEncKey Method](#M_Ecc_SaveEncKey) 

### C++ (STL) Equivalent

static int [dipki::Ecc::SaveEncKey](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#a069ed15422bafa4f727e6219de02ef64 "External link") (std::string outputFile, std::string internalKey, std::string password, PbeScheme pbes=PbeScheme::Default, std::string paramString="", Format fileFormat=Format::Binary)

### Python Equivalent

static [Ecc.save_enc_key](https://cryptosys.net/pki/pydocpki/class-stubs/Ecc.html#cryptosyspki.Ecc.save_enc_key "External link")(outputfile, intkeystr, password, pbescheme=0, params='', fileformat=0)

### Remarks

Use this function to save a private key in a new encrypted file format, perhaps with stronger encryption. 
Use the `PKI_KEY_FORMAT_PEM` flag to save in PEM-encoded format.
You must first read in the old private key file into an "internal" private key string which is only valid for the current session.

Valid values for the "prf" parameter in *szParams* are:

* `hmacWithSHA1` (default)
* `hmacWithSHA224`
* `hmacWithSHA256`
* `hmacWithSHA384`
* `hmacWithSHA512`

These are case-insensitive and work only with the `PKI_PBE_PBKDF2_` options. This will override any `PKI_HMAC_` flag in *nOptions*

Set *szParams* as the empty string `""` for defaults.

### Example

```

Dim nRet As Long
Dim nChars As Long
Dim strIntKey As String
Dim strPriKeyFile As String
Dim strPassword As String
Dim strNewKeyFile As String
Dim strTypeName As String
Dim strFileName As String

strPriKeyFile = "myeckeyp256.p8"
strPassword = "password"

' Find required length of internal key string
nChars = ECC_ReadPrivateKey("", 0, strPriKeyFile, strPassword, 0)
Debug.Print "ECC_ReadPrivateKey returns " & nChars & " (expected +ve)"
' Dimension the string to receive output
strIntKey = String(nChars, " ")
' Read it in
nChars = ECC_ReadPrivateKey(strIntKey, Len(strIntKey), strPriKeyFile, strPassword, 0)
Debug.Print "[" & strIntKey & "]"

' Now save in a different format: ECPrivatekey
strNewKeyFile = "myeckey.key"
nRet = ECC_SaveKey(strNewKeyFile, strIntKey, 0)
Debug.Print "ECC_SaveKey returns " & nRet & " (expected 0)"

' Check the types of file we made
strTypeName = String(PKI_ASN1_TYPE_MAXCHARS, " ")
strFileName = strNewKeyFile
nChars = ASN1_Type(strTypeName, Len(strTypeName), strFileName, 0)
If nChars > 0 Then Debug.Print strFileName & ": " & Left(strTypeName, nChars)

```

```

ECC_ReadPrivateKey returns 100 (expected +ve)
[PVECvfqrR9ge+DBQVJtnBBrw6gH+qmnZSX7apDuXoWcwmvIWLXNbXHG3Bo1cAXGuLUzIeWyb4M5G2aUnn/3Y/9d1/KjQjTnNXeky]
ECC_SaveKey returns 0 (expected 0)
myeckey.key: EC PRIVATE KEY

```

### See Also

[ECC_ReadPrivateKey](#ECC_ReadPrivateKey)
[ECC_SaveKey](#ECC_SaveKey)

[[Contents](#topofpage)] [[Index](#index)]

<a id="ECC_SaveKey"></a>ECC_SaveKey
-----------------------------------

Saves an internal EC key string to an unencrypted key file.

### VBA/VB6 Syntax

`Public Declare Function ECC_SaveKey Lib "diCrPKI.dll" (ByVal strFileOut As String, ByVal strIntKeyString As String, ByVal nOptions As Long) As Long`

`nRet = ECC_SaveKey(strFileOut, strIntKeyString, nOptions)`

### C/C++ Syntax

`long __stdcall ECC_SaveKey(const char *szFileOut, const char *szIntKeyString, long nOptions);`

### Parameters

*szFileOut*
:   [in] name of key file to be created.

*szIntKeyString*
:   [in] the private or public EC key in an internal key string.

*nOptions*
:   [in] choose one of
* `PKI_DEFAULT` (0) to save the key in the default format (see remarks).
* `PKI_KEY_TYPE_PKCS8` to save a NIST/SEC curve private key in PKCS#8 format.

and optionally add any of  

`PKI_KEY_FORMAT_PEM` to save the key file in PEM form (default is binary DER-encoded format). 

`PKI_KEY_LEGACY` to save a safe key in "legacy" PKCS#8 v1 format (default is v2 OneAsymmetricKey).

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`eccSaveKey`](#VB_eccSaveKey) (szOutputFile As String, szKeyStr As String, Optional nOptions As Long = 0) As Long

### .NET Equivalent

[Ecc.SaveKey Method](#M_Ecc_SaveKey) 

### C++ (STL) Equivalent

static int [dipki::Ecc::SaveKey](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#a555d6cf01c2630f0e225198723b9518b "External link") (std::string outputFile, std::string internalKey, KeyType keyType=KeyType::Default, Format fileFormat=Format::Binary)

### Python Equivalent

static [Ecc.save_key](https://cryptosys.net/pki/pydocpki/class-stubs/Ecc.html#cryptosyspki.Ecc.save_key "External link")(outputfile, intkeystr, keytype=0, fileformat=0)

### Remarks

EC public keys are always saved in `SubjectPublicKeyInfo` format [[RFC5480](#RFC5480)].
By default, NIST/SEC curve private keys are saved in `ECPrivateKey` format [[RFC5915](#RFC5915)].
Use the `PKI_KEY_TYPE_PKCS8` option to save in PKCS#8 `PrivateKeyInfo` format [[RFC5208](#RFC5208)].

*[New in v22.0]* Safe curve private keys (X25519, Ed25519, X448 and Ed448) are always saved in PKCS#8 v2 `OneAsymmetricKey` 
format including the public key [[RFC5958](#RFC5958)].
Add the option `PKI_KEY_LEGACY` to save in older PKCS#8 v1 `PrivateKeyInfo` format [[RFC5208](#RFC5208)]
excluding the public key.

To save a private key in encrypted form, use [ECC_SaveEncKey](#ECC_SaveEncKey).

### Example

```

Dim nRet As Long
Dim nChars As Long
Dim strIntKey As String
Dim strKeyFile As String
Dim strPassword As String
Dim strNewKeyFile As String
Dim strTypeName As String
Dim strFileName As String

strKeyFile = "myeckeyp256.p8"
strPassword = "password"

Debug.Print "FILE: " & strKeyFile
' Find required length of internal key string
nChars = ECC_ReadPrivateKey("", 0, strKeyFile, strPassword, 0)
Debug.Print "ECC_ReadPrivateKey returns " & nChars & " (expected +ve)"
' Dimension the string to receive output
strIntKey = String(nChars, " ")
' Read it in
nChars = ECC_ReadPrivateKey(strIntKey, Len(strIntKey), strKeyFile, strPassword, 0)
' Caution: internal key string is only valid for the current session
Debug.Print "[" & strIntKey & "]"

' Now save in a different format: ECPrivatekey in PEM encoding
strNewKeyFile = "myeckey.pem"
nRet = ECC_SaveKey(strNewKeyFile, strIntKey, PKI_KEY_FORMAT_PEM)
Debug.Print "ECC_SaveKey returns " & nRet & " (expected 0)"

' Check the type of file we made
strTypeName = String(PKI_ASN1_TYPE_MAXCHARS, " ")
strFileName = strNewKeyFile
nChars = ASN1_Type(strTypeName, Len(strTypeName), strFileName, 0)
If nChars > 0 Then Debug.Print strFileName & ": " & Left(strTypeName, nChars)

```

```

FILE: myeckeyp256.p8
ECC_ReadPrivateKey returns 100 (expected +ve)
[PVECF7UtCxnQIin+PBxnvYk8GsAsMbPfKYUnfZv/EU/oSeJtW1UAt1QMZT60Solrg6PtKLHsGlWT8IxgKTfzIf3+NK/Ulq0+z6Id]
ECC_SaveKey returns 0 (expected 0)
myeckey.pem: EC PRIVATE KEY

```

### See Also

[ECC_ReadPrivateKey](#ECC_ReadPrivateKey)
[ECC_ReadPublicKey](#ECC_ReadPublicKey)
[ECC_SaveEncKey](#ECC_SaveEncKey)
[ECC_PublicKeyFromPrivate](#ECC_PublicKeyFromPrivate)

[[Contents](#topofpage)] [[Index](#index)]

<a id="HASH_Bytes"></a>HASH_Bytes
---------------------------------

Creates a message digest hash as a byte array from byte data.
The hash algorithm to use is passed in the options parameter.

### VBA/VB6 Syntax

`Public Declare Function HASH_Bytes Lib "diCrPKI.dll" 
    (ByRef lpDigest As Byte, ByVal nDigLen As Long, ByRef lpMessage As Byte, 
    ByVal nMsgLen As Long, ByVal nOptions As Long) As Long`

`nRet = HASH_Bytes(lpDigest(0), nDigLen, lpMessage(0), nMsgLen, nOptions) ' Note the "(0)" after the byte array parameters`

### C/C++ Syntax

`long __stdcall HASH_Bytes(unsigned char *lpOutput, long nOutBytes, const void *lpMessage, long nMsgLen, long nOptions);`

### Parameters

*lpOutput*
:   [out] array to receive the hash digest.

*nOutBytes*
:   [in] specifying the length in bytes of the output array.

*lpMessage*
:   [in] array containing the message data

*nMsgLen*
:   [in] specifying length of the message data in bytes.

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_HASH_SHA1` (0) to use the SHA-1 algorithm (default)  

`PKI_HASH_SHA224` to use the SHA-224 algorithm  

`PKI_HASH_SHA256` to use the SHA-256 algorithm  

`PKI_HASH_SHA384` to use the SHA-384 algorithm  

`PKI_HASH_SHA512` to use the SHA-512 algorithm  

`PKI_HASH_SHA3_224` to use the SHA-3-224 algorithm  

`PKI_HASH_SHA3_256` to use the SHA-3-256 algorithm  

`PKI_HASH_SHA3_384` to use the SHA-3-384 algorithm  

`PKI_HASH_SHA3_512` to use the SHA-3-512 algorithm  

`PKI_HASH_MD5` to use the MD5 algorithm  

`PKI_HASH_MD2` to use the MD2 algorithm (legacy applications)  

`PKI_HASH_RMD160` to use the RIPEMD-160 algorithm  

`PKI_HASH_BTC160` to use the Bitcoin160 algorithm, `RIPEMD160(SHA256(m))`  

and optionally add  

`PKI_HASH_DOUBLE` to compute a double hash, `HASH(HASH(m))`

### Returns (VBA/C)

If successful, the return value is the number of bytes in the hash digest array; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`hashBytes`](#VB_hashBytes) (lpMessage() As Byte, nOptions As Long) As Byte()

### .NET Equivalent

[Hash.BytesFromBytes Method](#M_Hash_BytesFromBytes)  

[Hash.Double Method](#M_Hash_Double)  

### C++ (STL) Equivalent

static bvec_t [dipki::Hash::Bytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hash.html#ad7b2346b1e672cda85f4685feeb4e851 "External link") (const bvec_t &data, Alg alg=Alg::Sha1)

static [Hash.double](https://cryptosys.net/pki/pydocpki/class-stubs/Hash.html#cryptosyspki.Hash.double "External link")(data, alg=Alg.SHA1)

### Python Equivalent

`static [Hash.data](https://cryptosys.net/pki/pydocpki/class-stubs/Hash.html#cryptosyspki.Hash.data "External link")(data, alg=Alg.SHA1)`

static [Hash.double](https://cryptosys.net/pki/pydocpki/class-stubs/Hash.html#cryptosyspki.Hash.double "External link")(data, alg=Alg.SHA1)

### Remarks

Specify a zero *nDigLen* parameter to find out the required length of the output array.
The maximum possible length is `PKI_MAX_HASH_BYTES`.
Hint: SHA-1 requires 20 bytes; MD5 and MD2 require 16 bytes; SHA-512 requires 64. 
The final digest will be truncated to the specified length if less than the expected size. 

### Example (VBA core function)

```

    Dim nRet As Long
    Dim abDigest() As Byte
    Dim abMessage() As Byte
    Dim nMsgLen As Long
    ' Set up message to be hashed
    abMessage = StrConv("abc", vbFromUnicode)
    nMsgLen = UBound(abMessage) + 1
    ' Pre-dimension digest array (NB zero-based so subtract one)
    ReDim abDigest(PKI_MAX_HASH_BYTES - 1)
    ' Create default hash (SHA1)
    nRet = HASH_Bytes(abDigest(0), PKI_MAX_HASH_BYTES, abMessage(0), nMsgLen, 0)
    If nRet > 0 Then ReDim Preserve abDigest(nRet - 1)
    Debug.Print nRet, cnvHexStrFromBytes(abDigest)
    
    ' Repeat for MD5
    ReDim abDigest(PKI_MAX_HASH_BYTES - 1)
    nRet = HASH_Bytes(abDigest(0), PKI_MAX_HASH_BYTES, abMessage(0), nMsgLen, PKI_HASH_MD5)
    If nRet > 0 Then ReDim Preserve abDigest(nRet - 1)
    Debug.Print nRet, cnvHexStrFromBytes(abDigest)

```

The above example should produce the following output:

```

 20           A9993E364706816ABA3E25717850C26C9CD0D89D
 16           900150983CD24FB0D6963F7D28E17F72

```

### Example (VBA wrapper function)

```

Dim strDigest As String
Dim lpMessage() As Byte
Dim lpDigest() As Byte

' Hex <-- Hex
strDigest = hashHexFromHex("616263", PKI_HASH_SHA256)   ' "abc" in hex
Debug.Print strDigest
lpMessage = StrConv("abc", vbFromUnicode)   ' "abc" in a byte array
' Hex <-- Bytes
strDigest = hashHexFromBytes(lpMessage, PKI_HASH_SHA256)
Debug.Print strDigest
' Bytes <-- Bytes
lpDigest = hashBytes(lpMessage, PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)
' Hex <-- File
strDigest = hashHexFromFile("abc.txt", PKI_HASH_SHA256) ' "abc" in a text file
Debug.Print strDigest
' Bytes <-- File
lpDigest = hashFile("abc.txt", PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)

Debug.Print "OK=" & "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD"

```

```

Dim strDigest As String
Dim lpMessage() As Byte
Dim lpDigest() As Byte
lpDigest = hashBytes(lpMessage, PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)
lpDigest = hashBytes(lpMessage, PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)
strDigest = hashHexFromBytes(lpMessage, PKI_HASH_SHA256)
Debug.Print strDigest
strDigest = hashHexFromBytes(lpMessage, PKI_HASH_SHA512)
Debug.Print strDigest
strDigest = hashHexFromBytes(lpMessage, PKI_HASH_SHA512)
Debug.Print strDigest

```

### See Also

[HASH_HexFromBytes](#HASH_HexFromBytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="HASH_File"></a>HASH_File
-------------------------------

Creates a message digest hash in byte format for a file.
The hash algorithm to use is passed in the options parameter.

### VBA/VB6 Syntax

`Public Declare Function HASH_File Lib "diCrPKI.dll" 
    (ByRef lpDigest As Byte, ByVal nDigLen As Long, ByVal strFileName As String, 
    ByVal nOptions As Long) As Long`

`nRet = HASH_File(lpDigest(0), nDigLen, strFileName, nOptions)`

### C/C++ Syntax

`long __stdcall HASH_File(unsigned char *lpOutput, long nOutBytes, const char *szFileName, long nOptions);`

### Parameters

*lpOutput*
:   [out] array to receive the hash digest.

*nOutBytes*
:   [in] specifying the length in bytes of the output array.

*szFileName*
:   [in] containing the name of the file.

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_HASH_SHA1` (0) to use the SHA-1 algorithm (default)  

`PKI_HASH_SHA224` to use the SHA-224 algorithm  

`PKI_HASH_SHA256` to use the SHA-256 algorithm  

`PKI_HASH_SHA384` to use the SHA-384 algorithm  

`PKI_HASH_SHA512` to use the SHA-512 algorithm  

`PKI_HASH_SHA3_224` to use the SHA-3-224 algorithm  

`PKI_HASH_SHA3_256` to use the SHA-3-256 algorithm  

`PKI_HASH_SHA3_384` to use the SHA-3-384 algorithm  

`PKI_HASH_SHA3_512` to use the SHA-3-512 algorithm  

`PKI_HASH_MD5` to use the MD5 algorithm  

`PKI_HASH_MD2` to use the MD2 algorithm (legacy applications)  

`PKI_HASH_RMD160` to use the RIPEMD-160 algorithm  

`PKI_HASH_BTC160` to use the Bitcoin160 algorithm, `RIPEMD160(SHA256(m))`  

and optionally add  

`PKI_HASH_DOUBLE` to compute a double hash, `HASH(HASH(m))`  

and add 

`PKI_HASH_MODE_TEXT` to hash in "text" mode instead of default "binary" mode

### Returns (VBA/C)

If successful, the return value is the number of bytes in the hash digest array; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`hashFile`](#VB_hashFile) (szFileName As String, nOptions As Long) As Byte()

### .NET Equivalent

[Hash.BytesFromFile Method](#M_Hash_BytesFromFile)  

### C++ (STL) Equivalent

static bvec_t [dipki::Hash::File](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hash.html#a02207143699c3b81a57b54ffc8bc1729 "External link") (const std::string &fileName, Alg alg=Alg::Sha1, FileMode mode=FileMode::Binary)

### Python Equivalent

static [Hash.file](https://cryptosys.net/pki/pydocpki/class-stubs/Hash.html#cryptosyspki.Hash.file "External link")(filename, alg=Alg.SHA1)

### Remarks

Specify a zero *nOutBytes* parameter to find out the required length of the output array.
The maximum size will be `PKI_MAX_HASH_BYTES`. 
The final digest will be truncated to the specified length if less than the expected size. 
Add the option `PKI_HASH_MODE_TEXT` to work in "text" mode where CR-LF pairs are treated
as a single newline (LF) character. 
(This option is provided if you need to pass hash digests of text files between Windows and Unix systems.)
The default mode is "binary" where each byte is treated individually.
Only ANSI characters are supported in file names and paths.

### Examples

```

    Dim nRet As Long
    Dim abDigest() As Byte
    Dim sFileName As String
    
    ' File to be hashed contains a total of 13 bytes: "hello world" plus CR-LF
    ' 68 65 6c 6c 6f 20 77 6f 72 6c 64 0d 0a   hello world..

    sFileName = "hello.txt"
    
    ' Pre-dimension digest array - do this each time
    ReDim abDigest(PKI_MAX_HASH_BYTES)
    
    ' Create default hash (SHA1) in binary mode
    nRet = HASH_File(abDigest(0), PKI_MAX_HASH_BYTES, sFileName, 0)
    If nRet > 0 Then ReDim Preserve abDigest(nRet - 1)
    Debug.Print nRet, cnvHexStrFromBytes(abDigest)
    
    ' Use SHA1 in "text" mode
    ReDim abDigest(PKI_MAX_HASH_BYTES)
    nRet = HASH_File(abDigest(0), PKI_MAX_HASH_BYTES, sFileName, PKI_HASH_MODE_TEXT)
    If nRet > 0 Then ReDim Preserve abDigest(nRet - 1)
    Debug.Print nRet, cnvHexStrFromBytes(abDigest)
    
    ' Use MD5
    ReDim abDigest(PKI_MAX_HASH_BYTES)
    nRet = HASH_File(abDigest(0), PKI_MAX_HASH_BYTES, sFileName, PKI_HASH_MD5)
    If nRet > 0 Then ReDim Preserve abDigest(nRet - 1)
    Debug.Print nRet, cnvHexStrFromBytes(abDigest)
    
    ' Use MD5 in "text" mode
    ReDim abDigest(PKI_MAX_HASH_BYTES)
    nRet = HASH_File(abDigest(0), PKI_MAX_HASH_BYTES, sFileName, PKI_HASH_MD5 Or PKI_HASH_MODE_TEXT)
    If nRet > 0 Then ReDim Preserve abDigest(nRet - 1)
    Debug.Print nRet, cnvHexStrFromBytes(abDigest)

```

This should produce the following output:

```

 20           88A5B867C3D110207786E66523CD1E4A484DA697
 20           22596363B3DE40B06F981FB85D82312E8C0ED511
 16           A0F2A3C1DCD5B1CAC71BF0C03F2FF1BD
 16           6F5902AC237024BDD0C176CB93063DC4

```

### Example (VBA wrapper function)

```

Dim strDigest As String
Dim lpMessage() As Byte
Dim lpDigest() As Byte

' Hex <-- Hex
strDigest = hashHexFromHex("616263", PKI_HASH_SHA256)   ' "abc" in hex
Debug.Print strDigest
lpMessage = StrConv("abc", vbFromUnicode)   ' "abc" in a byte array
' Hex <-- Bytes
strDigest = hashHexFromBytes(lpMessage, PKI_HASH_SHA256)
Debug.Print strDigest
' Bytes <-- Bytes
lpDigest = hashBytes(lpMessage, PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)
' Hex <-- File
strDigest = hashHexFromFile("abc.txt", PKI_HASH_SHA256) ' "abc" in a text file
Debug.Print strDigest
' Bytes <-- File
lpDigest = hashFile("abc.txt", PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)

Debug.Print "OK=" & "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD"

```

### See Also

[HASH_HexFromFile](#HASH_HexFromFile)

[[Contents](#topofpage)] [[Index](#index)]

<a id="HASH_HexFromBytes"></a>HASH_HexFromBytes
-----------------------------------------------

Creates a message digest hash in hexadecimal format from byte (or string) data.
The hash algorithm to use is passed in the options parameter.

### VBA/VB6 Syntax

`Public Declare Function HASH_HexFromBytes Lib "diCrPKI.dll" 
(ByVal strOutput As String, ByVal nOutChars As Long, ByRef lpMessage As Byte, ByVal nMsgLen As Long, 
ByVal nOptions As Long) As Long`

Alternative for VB6/VBA only:-  

`Public Declare Function HASH_HexFromString Lib "diCrPKI.dll" Alias "HASH_HexFromBytes" 
(ByVal strOutput As String, ByVal nOutChars As Long, ByVal strMessage As String, ByVal nMsgLen As Long, 
ByVal nOptions As Long) As Long`

`nRet = HASH_HexFromBytes(strOutput, nOutChars, lpMessage(0), nMsgLen, nOptions)  

nRet = HASH_HexFromString(strOutput, nOutChars, strMessage, nMsgLen, nOptions)`

### C/C++ Syntax

`long __stdcall HASH_HexFromBytes(char *szOutput, long nOutChars, const void *lpMessage, long nMsgLen, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive hash digest in hexadecimal format.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*lpMessage*
:   [in] array containing the message data; or

*nMsgLen*
:   [in] specifying length of the message data in bytes.

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_HASH_SHA1` (0) to use the SHA-1 algorithm (default)  

`PKI_HASH_SHA224` to use the SHA-224 algorithm  

`PKI_HASH_SHA256` to use the SHA-256 algorithm  

`PKI_HASH_SHA384` to use the SHA-384 algorithm  

`PKI_HASH_SHA512` to use the SHA-512 algorithm  

`PKI_HASH_SHA3_224` to use the SHA-3-224 algorithm  

`PKI_HASH_SHA3_256` to use the SHA-3-256 algorithm  

`PKI_HASH_SHA3_384` to use the SHA-3-384 algorithm  

`PKI_HASH_SHA3_512` to use the SHA-3-512 algorithm  

`PKI_HASH_MD5` to use the MD5 algorithm  

`PKI_HASH_MD2` to use the MD2 algorithm (legacy applications)  

`PKI_HASH_RMD160` to use the RIPEMD-160 algorithm  

`PKI_HASH_BTC160` to use the Bitcoin160 algorithm, `RIPEMD160(SHA256(m))`  

and optionally add  

`PKI_HASH_DOUBLE` to compute a double hash, `HASH(HASH(m))`

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`hashHexFromBytes`](#VB_hashHexFromBytes) (lpMessage() As Byte, nOptions As Long) As String

### .NET Equivalent

[Hash.HexFromBytes Method](#M_Hash_HexFromBytes)  

[Hash.HexFromString Method](#M_Hash_HexFromString)  

### C++ (STL) Equivalent

static std::string [dipki::Hash::HexFromBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hash.html#ad21a696ec3eadb80d1f362c5ad7fc0f8 "External link") (const bvec_t &data, Alg alg=Alg::Sha1)

### Python Equivalent

static [Hash.hex_from_data](https://cryptosys.net/pki/pydocpki/class-stubs/Hash.html#cryptosyspki.Hash.hex_from_data "External link")(data, alg=Alg.SHA1)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The maximum number of output characters is `PKI_MAX_HASH_CHARS` (C/C++ users add one).

The final digest will be truncated to the specified length if less than the expected size. 

### Examples

```

Dim nRet As Long
Dim sDigest As String
Dim abMessage() As Byte
' Set up message to be hashed in unambiguous Byte format
abMessage = StrConv("abc", vbFromUnicode)
' Pre-dimension digest string
sDigest = String(PKI_MAX_HASH_CHARS, " ")
' Create default hash (SHA1)
nRet = HASH_HexFromBytes(sDigest, Len(sDigest), abMessage(0), 3, 0)
Debug.Print nRet, Left(sDigest, nRet)
' Explicitly use SHA1
nRet = HASH_HexFromBytes(sDigest, Len(sDigest), abMessage(0), 3, PKI_HASH_SHA1)
Debug.Print nRet, Left(sDigest, nRet)
' Pre-dimension digest string and use MD5
sDigest = String(PKI_MD5_CHARS, " ")
nRet = HASH_HexFromBytes(sDigest, Len(sDigest), abMessage(0), 3, PKI_HASH_MD5)
Debug.Print nRet, sDigest
' Pre-dimension digest string and use MD2
sDigest = String(PKI_MD5_CHARS, " ")
nRet = HASH_HexFromBytes(sDigest, Len(sDigest), abMessage(0), 3, PKI_HASH_MD2)
Debug.Print nRet, sDigest
' Make output string shorter - only get back that many chars
sDigest = String(16, " ")
nRet = HASH_HexFromBytes(sDigest, Len(sDigest), abMessage(0), 3, PKI_HASH_SHA1)
Debug.Print nRet, sDigest

```

The above example should produce the following output:

```

 40 a9993e364706816aba3e25717850c26c9cd0d89d
 40 a9993e364706816aba3e25717850c26c9cd0d89d
 32 900150983cd24fb0d6963f7d28e17f72
 32 da853b0d3f88d99b30283a69e6ded6bb
 16 a9993e364706816a

```

Alternative using `String` type directly (assumes 8-bit ANSI characters in strMessage):

```

Dim nRet As Long
Dim sDigest As String
Dim strMessage As String

strMessage = "abc"
' Pre-dimension digest string
sDigest = String(40, " ")
' Create default hash (SHA1)
nRet = HASH_HexFromString(sDigest, Len(sDigest), strMessage, Len(strMessage), 0)
Debug.Print nRet, sDigest

```

Example in C code (in C we are less fussed about the distinction between `char`
and `unsigned char` types when dealing with nonzero ANSI characters):

```

long lRet;
char szDigest[PKI_MAX_HASH_CHARS+1]; /* NB add one */
char message[] = "abc";

/* Compute default SHA-1 digest */
lRet = HASH_HexFromBytes(szDigest, sizeof(szDigest)-1, 
	(unsigned char*)message, strlen(message), 0);
assert(lRet > 0);
printf("SHA1('abc')=%s\n", szDigest);
/* Compute MD5 digest */
lRet = HASH_HexFromBytes(szDigest, sizeof(szDigest)-1, 
	(unsigned char*)message, strlen(message), PKI_HASH_MD5);
assert(lRet > 0);
printf("MD5('abc')=%s\n", szDigest);
/* Compute MD2 digest */
lRet = HASH_HexFromBytes(szDigest, sizeof(szDigest)-1, 
	(unsigned char*)message, strlen(message), PKI_HASH_MD2);
assert(lRet > 0);
printf("MD2('abc')=%s\n", szDigest);

```

This should produce the output

```

SHA1('abc')=a9993e364706816aba3e25717850c26c9cd0d89d
MD5('abc')=900150983cd24fb0d6963f7d28e17f72
MD2('abc')=da853b0d3f88d99b30283a69e6ded6bb

```

### Example (VBA wrapper function)

```

Dim strDigest As String
Dim lpMessage() As Byte
Dim lpDigest() As Byte

' Hex <-- Hex
strDigest = hashHexFromHex("616263", PKI_HASH_SHA256)   ' "abc" in hex
Debug.Print strDigest
lpMessage = StrConv("abc", vbFromUnicode)   ' "abc" in a byte array
' Hex <-- Bytes
strDigest = hashHexFromBytes(lpMessage, PKI_HASH_SHA256)
Debug.Print strDigest
' Bytes <-- Bytes
lpDigest = hashBytes(lpMessage, PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)
' Hex <-- File
strDigest = hashHexFromFile("abc.txt", PKI_HASH_SHA256) ' "abc" in a text file
Debug.Print strDigest
' Bytes <-- File
lpDigest = hashFile("abc.txt", PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)
Debug.Print "OK=" & "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD"

```

```

Dim strData As String
Dim strDigest As String
' Our original string data
strData = "Estándares de Electrónica de México para mañana"
' Compute SHA-1 hash over UTF-8 encoded byte array
strDigest = hashHexFromBytes(cnvUTF8BytesFromLatin1(strData), PKI_HASH_SHA1)
Debug.Print "Digest=" & strDigest
```

### See Also

[HASH_HexFromFile](#HASH_HexFromFile)
[HASH_Bytes](#HASH_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="HASH_HexFromFile"></a>HASH_HexFromFile
---------------------------------------------

Creates a message digest hash in hexadecimal format for a file.
The hash algorithm to use is passed in the options parameter.

### VBA/VB6 Syntax

`Public Declare Function HASH_HexFromFile Lib "diCrPKI.dll" 
(ByVal strOutput As String, ByVal nOutChars As Long, ByVal strFileName As String, 
ByVal nOptions As Long) As Long`

`nRet = HASH_HexFromFile(strOutput, nOutChars, strFileName, nOptions)`

### C/C++ Syntax

`long __stdcall HASH_HexFromFile(char *szOutput, long nOutChars, const char *szFileName, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive hash digest in hexadecimal format.

*nOutChars*
:   [in] specifying the maximum number of characters to be received in characters.

*szFileName*
:   [in] containing the name of the file.

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_HASH_SHA1` (0) to use the SHA-1 algorithm (default)  

`PKI_HASH_SHA224` to use the SHA-224 algorithm  

`PKI_HASH_SHA256` to use the SHA-256 algorithm  

`PKI_HASH_SHA384` to use the SHA-384 algorithm  

`PKI_HASH_SHA512` to use the SHA-512 algorithm  

`PKI_HASH_SHA3_224` to use the SHA-3-224 algorithm  

`PKI_HASH_SHA3_256` to use the SHA-3-256 algorithm  

`PKI_HASH_SHA3_384` to use the SHA-3-384 algorithm  

`PKI_HASH_SHA3_512` to use the SHA-3-512 algorithm  

`PKI_HASH_MD5` to use the MD5 algorithm  

`PKI_HASH_MD2` to use the MD2 algorithm (legacy applications)  

`PKI_HASH_RMD160` to use the RIPEMD-160 algorithm  

`PKI_HASH_BTC160` to use the Bitcoin160 algorithm, `RIPEMD160(SHA256(m))`  

and optionally add  

`PKI_HASH_DOUBLE` to compute a double hash, `HASH(HASH(m))`  

and add 

`PKI_HASH_MODE_TEXT` to hash in "text" mode instead of default "binary" mode

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`hashHexFromFile`](#VB_hashHexFromFile) (szFileName As String, nOptions As Long) As String

### .NET Equivalent

[Hash.HexFromFile Method](#M_Hash_HexFromFile)  

[Hash.HexFromTextFile Method](#M_Hash_HexFromTextFile)  

### C++ (STL) Equivalent

static std::string [dipki::Hash::HexFromFile](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hash.html#a20201d2aa3e4eb8372616ff1d3a0361c "External link") (const std::string &fileName, Alg alg=Alg::Sha1, FileMode mode=FileMode::Binary)

### Python Equivalent

static [Hash.hex_from_file](https://cryptosys.net/pki/pydocpki/class-stubs/Hash.html#cryptosyspki.Hash.hex_from_file "External link")(filename, alg=Alg.SHA1)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The maximum number of output characters will be `PKI_MAX_HASH_CHARS` (C/C++ users add one). 
The final digest will be truncated to the specified length if less than the expected size. 
Add the option `PKI_HASH_MODE_TEXT` to work in "text" mode where CR-LF pairs are treated
as a single newline (LF) character. 
(This option is provided if you need to pass hash digests of text files between Windows and Unix systems.)
The default mode is "binary" where each byte is treated individually.
Only ANSI characters are supported in file names and paths.

### Examples

```

Dim nRet As Long
Dim sDigest As String
Dim sFileName As String

' File to be hashed contains a total of 13 bytes: "hello world" plus CR-LF
' 68 65 6c 6c 6f 20 77 6f 72 6c 64 0d 0a   hello world..

sFileName = "hello.txt"

' Pre-dimension digest string
sDigest = String(PKI_MAX_HASH_CHARS, " ")

' Create default hash (SHA1) in binary mode
nRet = HASH_HexFromFile(sDigest, Len(sDigest), sFileName, 0)
Debug.Print nRet, Left(sDigest, nRet)
' Use SHA1 in "text" mode
nRet = HASH_HexFromFile(sDigest, Len(sDigest), sFileName, PKI_HASH_MODE_TEXT)
Debug.Print nRet, Left(sDigest, nRet)
' Use MD5
nRet = HASH_HexFromFile(sDigest, Len(sDigest), sFileName, PKI_HASH_MD5)
Debug.Print nRet, Left(sDigest, nRet)
' Use MD5 in "text" mode
nRet = HASH_HexFromFile(sDigest, Len(sDigest), sFileName, PKI_HASH_MD5 Or PKI_HASH_MODE_TEXT)
Debug.Print nRet, Left(sDigest, nRet)

```

This should produce the following output:

```

 40           88a5b867c3d110207786e66523cd1e4a484da697
 40           22596363b3de40b06f981fb85d82312e8c0ed511
 32           a0f2a3c1dcd5b1cac71bf0c03f2ff1bd
 32           6f5902ac237024bdd0c176cb93063dc4

```

### Example (VBA wrapper function)

```

Dim strDigest As String
Dim lpMessage() As Byte
Dim lpDigest() As Byte

' Hex <-- Hex
strDigest = hashHexFromHex("616263", PKI_HASH_SHA256)   ' "abc" in hex
Debug.Print strDigest
lpMessage = StrConv("abc", vbFromUnicode)   ' "abc" in a byte array
' Hex <-- Bytes
strDigest = hashHexFromBytes(lpMessage, PKI_HASH_SHA256)
Debug.Print strDigest
' Bytes <-- Bytes
lpDigest = hashBytes(lpMessage, PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)
' Hex <-- File
strDigest = hashHexFromFile("abc.txt", PKI_HASH_SHA256) ' "abc" in a text file
Debug.Print strDigest
' Bytes <-- File
lpDigest = hashFile("abc.txt", PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)

Debug.Print "OK=" & "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD"

```

### See Also

[HASH_HexFromBytes](#HASH_HexFromBytes)
[HASH_File](#HASH_File)

[[Contents](#topofpage)] [[Index](#index)]

<a id="HASH_HexFromHex"></a>HASH_HexFromHex
-------------------------------------------

Creates a message digest hash in hexadecimal format from data in a 
hexadecimal-encoded string.
The hash algorithm to use is passed in the options parameter.

### VBA/VB6 Syntax

`Public Declare Function HASH_HexFromHex Lib "diCrPKI.dll" 
(ByVal strOutput As String, ByVal nMaxChars As Long, ByVal strMsgHex As String, ByVal nOptions As Long) As Long`

`nRet = HASH_HexFromHex(strOutput, nMaxChars, strMsgHex, nOptions)`

### C/C++ Syntax

`long __stdcall HASH_HexFromHex(char *szOutput, long nOutChars, const char *szMsgHex, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive hash digest in hexadecimal format.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szMsgHex*
:   [in] containing the message data in hexadecimal-encoded format.

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_HASH_SHA1` (0) to use the SHA-1 algorithm (default)  

`PKI_HASH_SHA224` to use the SHA-224 algorithm  

`PKI_HASH_SHA256` to use the SHA-256 algorithm  

`PKI_HASH_SHA384` to use the SHA-384 algorithm  

`PKI_HASH_SHA512` to use the SHA-512 algorithm  

`PKI_HASH_SHA3_224` to use the SHA-3-224 algorithm  

`PKI_HASH_SHA3_256` to use the SHA-3-256 algorithm  

`PKI_HASH_SHA3_384` to use the SHA-3-384 algorithm  

`PKI_HASH_SHA3_512` to use the SHA-3-512 algorithm  

`PKI_HASH_MD5` to use the MD5 algorithm  

`PKI_HASH_MD2` to use the MD2 algorithm (legacy applications)  

`PKI_HASH_RMD160` to use the RIPEMD-160 algorithm  

`PKI_HASH_BTC160` to use the Bitcoin160 algorithm, `RIPEMD160(SHA256(m))`  

and optionally add  

`PKI_HASH_DOUBLE` to compute a double hash, `HASH(HASH(m))`

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`hashHexFromHex`](#VB_hashHexFromHex) (szMsgHex As String, nOptions As Long) As String

### .NET Equivalent

[Hash.HexFromHex Method](#M_Hash_HexFromHex)  

### C++ (STL) Equivalent

static std::string [dipki::Hash::HexFromHex](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hash.html#a32622d3a194234770744e300db0215f0 "External link") (const std::string &dataHex, Alg alg=Alg::Sha1)

### Python Equivalent

static [Hash.hex_from_hex](https://cryptosys.net/pki/pydocpki/class-stubs/Hash.html#cryptosyspki.Hash.hex_from_hex "External link")(datahex, alg=Alg.SHA1)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The maximum number of output characters is `PKI_MAX_HASH_CHARS` (C/C++ users add one).
The final digest will be truncated to the specified length if less than the expected size. 
Valid input hex digits are [0-9A-Fa-f]. The output is always in lower-case letters.

### Example (VBA core function)

```

Dim strDigest As String
Dim nRet As Long
Dim strData As String
' Compute SHA-1("abc")
strDigest = String(PKI_SHA1_CHARS, " ")
strData = "616263"
nRet = HASH_HexFromHex(strDigest, Len(strDigest), strData, PKI_HASH_SHA1)
Debug.Print strDigest
' Compute SHA-224("abc")
strDigest = String(PKI_SHA224_CHARS, " ")
strData = "616263"
nRet = HASH_HexFromHex(strDigest, Len(strDigest), strData, PKI_HASH_SHA224)
Debug.Print strDigest

```

This should produce the following output:

```

a9993e364706816aba3e25717850c26c9cd0d89d
23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7

```

### Example (VBA wrapper function)

```

Dim strDigest As String
Dim lpMessage() As Byte
Dim lpDigest() As Byte

' Hex <-- Hex
strDigest = hashHexFromHex("616263", PKI_HASH_SHA256)   ' "abc" in hex
Debug.Print strDigest
lpMessage = StrConv("abc", vbFromUnicode)   ' "abc" in a byte array
' Hex <-- Bytes
strDigest = hashHexFromBytes(lpMessage, PKI_HASH_SHA256)
Debug.Print strDigest
' Bytes <-- Bytes
lpDigest = hashBytes(lpMessage, PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)
' Hex <-- File
strDigest = hashHexFromFile("abc.txt", PKI_HASH_SHA256) ' "abc" in a text file
Debug.Print strDigest
' Bytes <-- File
lpDigest = hashFile("abc.txt", PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)

Debug.Print "OK=" & "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD"

```

### See Also

[HASH_HexFromBytes](#HASH_HexFromBytes)
[HASH_Bytes](#HASH_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="HASH_Length"></a>HASH_Length
-----------------------------------

Return length of message digest output in bytes.

### VBA/VB6 Syntax

`Public Declare Function HASH_Length Lib "diCrPKI.dll" (ByVal nAlgId As Long) As Long`

`nRet = HASH_Length(nAlgId)`

### C/C++ Syntax

`long __stdcall HASH_Length(long nAlgId);`

### Parameters

*nAlgId*
:   [in] Algorithm Id flag. Select one of `PKI_HASH_*` or `PKI_HMAC_*`, for example:  

`PKI_HASH_SHA1` SHA-1 algorithm  

`PKI_HASH_SHA224` SHA-224 algorithm  

`PKI_HASH_SHA256` SHA-256 algorithm  

`PKI_HASH_SHA384` SHA-384 algorithm  

`PKI_HASH_SHA512` SHA-512 algorithm  

`PKI_HASH_SHA3_224` SHA-3-224 algorithm  

`PKI_HASH_SHA3_256` SHA-3-256 algorithm  

`PKI_HASH_SHA3_384` SHA-3-384 algorithm  

`PKI_HASH_SHA3_512` SHA-3-512 algorithm  

`PKI_HASH_MD5` MD5 algorithm  

`PKI_HASH_MD2` MD2 algorithm  

`PKI_HASH_RMD160` RIPEMD-160 algorithm  

`PKI_HASH_BTC160` Bitcoin160 algorithm, `RIPEMD160(SHA256(m))`

### Returns (VBA/C)

Length of the hash function output in bytes; 
else a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`hashLength`](#VB_hashLength) (nAlgId As Long) As Long

### .NET Equivalent

[Hash.Length Method](#M_Hash_Length)  

### C++ (STL) Equivalent

static int [dipki::Hash::Length](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hash.html#a14f9dc55c1f84a66f7729b64e70dd740 "External link") (Alg alg)

### Python Equivalent

static [Hash.length](https://cryptosys.net/pki/pydocpki/class-stubs/Hash.html#cryptosyspki.Hash.length "External link")(alg)

### Remarks

*[New in v20.5]*

### Example (VBA core function)

```

Debug.Print Hash_Length(PKI_HASH_SHA512)
' 64

```

### Example (VBA wrapper function)

```

Debug.Print hashLength(PKI_HASH_BTC160)
' 20

```

### See Also

[[Contents](#topofpage)] [[Index](#index)]

<a id="HMAC_Bytes"></a>HMAC_Bytes
---------------------------------

Creates a keyed-hash based message authentication code (HMAC)
as a byte array from byte data.
The hash algorithm to use is passed in the options parameter.

### VBA/VB6 Syntax

`Public Declare Function HMAC_Bytes Lib "diCrPKI.dll" 
(ByRef lpDigest As Byte, ByVal nDigLen As Long, ByRef lpMessage As Byte, 
ByVal nMsgLen As Long, ByRef lpKey As Byte, ByVal nKeyLen As Long, ByVal nOptions As Long) As Long`

`nRet = HMAC_Bytes(lpDigest(0), nDigLen, lpMessage(0), nMsgLen, lpKey(0), nKeyLen, nOptions) ' Note the "(0)" after the byte array parameters`

### C/C++ Syntax

`long __stdcall HMAC_Bytes(unsigned char *lpOutput, long nOutBytes, const void *lpMessage, long nMsgLen, const void *lpKey, long nKeyLen, long nOptions);`

### Parameters

*lpOutput*
:   [out] array to receive the hash digest.

*nOutBytes*
:   [in] specifying the length in bytes of the output array.

*lpMessage*
:   [in] array containing the message data

*nMsgLen*
:   [in] specifying length of the message data in bytes.

*lpKey*
:   [in] array containing the key

*nKeyLen*
:   [in] specifying length of the key in bytes.

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_HASH_SHA1` (0) to use the SHA-1 algorithm (default)  

`PKI_HASH_SHA224` to use the SHA-224 algorithm  

`PKI_HASH_SHA256` to use the SHA-256 algorithm  

`PKI_HASH_SHA384` to use the SHA-384 algorithm  

`PKI_HASH_SHA512` to use the SHA-512 algorithm  

`PKI_HASH_SHA3_224` to use the SHA-3-224 algorithm  

`PKI_HASH_SHA3_256` to use the SHA-3-256 algorithm  

`PKI_HASH_SHA3_384` to use the SHA-3-384 algorithm  

`PKI_HASH_SHA3_512` to use the SHA-3-512 algorithm  

`PKI_HASH_MD5` to use the MD5 algorithm

### Returns (VBA/C)

If successful, the return value is the number of bytes in the output array; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`hmacBytes`](#VB_hmacBytes) (lpMessage() As Byte, lpKey() As Byte, nOptions As Long) As Byte()

### .NET Equivalent

[Hmac.BytesFromBytes Method](#M_Hmac_BytesFromBytes)  

### C++ (STL) Equivalent

static bvec_t [dipki::Hmac::Bytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hmac.html#ae6e138b6d6c13d03e2dbd2953a03c902 "External link") (const bvec_t &data, const bvec_t &key, Alg alg=Alg::Sha1)

### Python Equivalent

static [Hmac.data](https://cryptosys.net/pki/pydocpki/class-stubs/Hmac.html#cryptosyspki.Hmac.data "External link")(data, key, alg=Alg.SHA1)

### Remarks

Specify a zero *nDigLen* parameter to find out the required length of the output array,
or use the appropriate `PKI_XXX_BYTES` constant.
The maximum possible length is `PKI_MAX_HASH_BYTES`.
The final digest will be truncated to the specified length if less than the expected size. 
MD2 is not available with the HMAC functions.

### Example (VBA core function)

```

Dim abData() As Byte
Dim abKey() As Byte
Dim nDataLen As Long
Dim nKeyLen As Long
Dim abDigest() As Byte
Dim nDigLen As Long
Dim nRet As Long
Dim i As Long

' Test case 4 from RFC 2202 and RFC 4231
' key =           0x0102030405060708090a0b0c0d0e0f10111213141516171819
' key_len         25
' data =          0xcd repeated 50 times
' data_len =      50

nKeyLen = 25
ReDim abKey(nKeyLen - 1)
For i = 0 To nKeyLen - 1
    abKey(i) = CByte(i + 1)
Next
Debug.Print "Key=" & cnvHexStrFromBytes(abKey)
nDataLen = 50
ReDim abData(nDataLen - 1)
For i = 0 To nDataLen - 1
    abData(i) = &HCD
Next

' Compute default HMAC (HMAC-SHA-1)
nDigLen = PKI_SHA1_BYTES
ReDim abDigest(nDigLen - 1)
nRet = HMAC_Bytes(abDigest(0), nDigLen, abData(0), nDataLen, abKey(0), nKeyLen, PKI_HASH_SHA1)
If nRet <= 0 Then Exit Sub ' ERROR
Debug.Print "HMAC-SHA-1  =" & cnvHexStrFromBytes(abDigest)
Debug.Print "CORRECT     =" & "4c9007f4026250c6bc8414f9bf50c86c2d7235da"

' Compute HMAC-MD5
nDigLen = PKI_MD5_BYTES
ReDim abDigest(nDigLen - 1)
nRet = HMAC_Bytes(abDigest(0), nDigLen, abData(0), nDataLen, abKey(0), nKeyLen, PKI_HASH_MD5)
If nRet <= 0 Then Exit Sub ' ERROR
Debug.Print "HMAC-MD5    =" & cnvHexStrFromBytes(abDigest)
Debug.Print "CORRECT     =" & "697eaf0aca3a3aea3a75164746ffaa79"

' Compute HMAC-SHA-256
nDigLen = PKI_SHA256_BYTES
ReDim abDigest(nDigLen - 1)
nRet = HMAC_Bytes(abDigest(0), nDigLen, abData(0), nDataLen, abKey(0), nKeyLen, PKI_HASH_SHA256)
If nRet <= 0 Then Exit Sub ' ERROR
Debug.Print "HMAC-SHA-256=" & cnvHexStrFromBytes(abDigest)
Debug.Print "CORRECT     =" & "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b"

```

The above example should produce the following output:

```

Key=0102030405060708090A0B0C0D0E0F10111213141516171819
HMAC-SHA-1  =4C9007F4026250C6BC8414F9BF50C86C2D7235DA
CORRECT     =4c9007f4026250c6bc8414f9bf50c86c2d7235da
HMAC-MD5    =697EAF0ACA3A3AEA3A75164746FFAA79
CORRECT     =697eaf0aca3a3aea3a75164746ffaa79
HMAC-SHA-256=82558A389A443C0EA4CC819899F2083A85F0FAA3E578F8077A2E3FF46729665B
CORRECT     =82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b

```

### Example (VBA wrapper function)

```

Dim strDigest As String
Dim lpMessage() As Byte
Dim lpDigest() As Byte
Dim lpKey() As Byte
lpKey = cnvBytesFromHexStr("0102030405060708090a0b0c0d0e0f10111213141516171819")
lpDigest = hmacBytes(lpMessage, lpKey, PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)
lpDigest = hmacBytes(lpMessage, lpKey, PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)
strDigest = hmacHexFromBytes(lpMessage, lpKey, PKI_HASH_SHA256)
Debug.Print strDigest
strDigest = hmacHexFromBytes(lpMessage, lpKey, PKI_HASH_SHA512)
Debug.Print strDigest
strDigest = hmacHexFromBytes(lpMessage, lpKey, PKI_HASH_SHA512)
Debug.Print strDigest

```

```

Dim lpData() As Byte
Dim lpKey() As Byte
Dim lpDigest() As Byte
Dim strDigest As String

' Test case 4 from RFC 2202 and RFC 4231
lpKey = cnvBytesFromHexStr("0102030405060708090a0b0c0d0e0f10111213141516171819")
' data = 0xcd repeated 50 times
lpData = cnvBytesFromHexStr("cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" & _
    "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd")
' Bytes <-- Bytes
lpDigest = hmacBytes(lpData, lpKey, PKI_HASH_SHA256)
Debug.Print "HMAC-SHA-256=" & cnvHexStrFromBytes(lpDigest)
Debug.Print "CORRECT     =82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b"
' Hex <-- Bytes
strDigest = hmacHexFromBytes(lpData, lpKey, PKI_HASH_SHA256)
Debug.Print "HMAC-SHA-256=" & strDigest

' Hex <-- Hex
' Test case 1 from RFC 2202 and RFC 4231
' Data = "Hi There"
strDigest = hmacHexFromHex("4869205468657265", "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", PKI_HASH_SHA256)
Debug.Print "HMAC-SHA-256=" & strDigest
Debug.Print "CORRECT     =b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"

```

### See Also

[HMAC_HexFromBytes](#HMAC_HexFromBytes)
[HMAC_HexFromHex](#HMAC_HexFromHex)

[[Contents](#topofpage)] [[Index](#index)]

<a id="HMAC_HexFromBytes"></a>HMAC_HexFromBytes
-----------------------------------------------

Creates a keyed-hash based message authentication code (HMAC) 
 in hexadecimal format from byte data.
The hash algorithm to use is passed in the options parameter.

### VBA/VB6 Syntax

`Public Declare Function HMAC_HexFromBytes Lib "diCrPKI.dll" 
(ByVal strOutput As String, ByVal nOutChars As Long, ByRef lpMessage As Byte, 
ByVal nMsgLen As Long, ByRef lpKey As Byte, ByVal nKeyLen As Long, ByVal nOptions As Long) As Long`

`nRet = HMAC_HexFromBytes(strOutput, nOutChars, lpMessage(0), nMsgLen, lpKey(0), nKeyLen, nOptions)`

### C/C++ Syntax

`long __stdcall HMAC_HexFromBytes(char *szOutput, long nOutChars, const void *lpMessage, long nMsgLen, const void *lpKey, long nKeyLen, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive output in hexadecimal format.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*lpMessage*
:   [in] array containing the message data in a byte array

*nMsgLen*
:   [in] specifying length of the message data in bytes.

*lpKey*
:   [in] array containing the key in a byte array

*nKeyLen*
:   [in] specifying length of the key in bytes.

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_HASH_SHA1` (0) to use the SHA-1 algorithm (default)  

`PKI_HASH_SHA224` to use the SHA-224 algorithm  

`PKI_HASH_SHA256` to use the SHA-256 algorithm  

`PKI_HASH_SHA384` to use the SHA-384 algorithm  

`PKI_HASH_SHA512` to use the SHA-512 algorithm  

`PKI_HASH_SHA3_224` to use the SHA-3-224 algorithm  

`PKI_HASH_SHA3_256` to use the SHA-3-256 algorithm  

`PKI_HASH_SHA3_384` to use the SHA-3-384 algorithm  

`PKI_HASH_SHA3_512` to use the SHA-3-512 algorithm  

`PKI_HASH_MD5` to use the MD5 algorithm

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`hmacHexFromBytes`](#VB_hmacHexFromBytes) (lpMessage() As Byte, lpKey() As Byte, nOptions As Long) As String

### .NET Equivalent

[Hmac.HexFromBytes Method](#M_Hmac_HexFromBytes)  

### C++ (STL) Equivalent

static std::string [dipki::Hmac::HexFromBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hmac.html#a42d50f89e1642e1256c499bfb3c93863 "External link") (const bvec_t &data, const bvec_t &key, Alg alg=Alg::Sha1)

### Python Equivalent

static [Hmac.hex_from_data](https://cryptosys.net/pki/pydocpki/class-stubs/Hmac.html#cryptosyspki.Hmac.hex_from_data "External link")(data, key, alg=Alg.SHA1)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The maximum number of output characters is `PKI_MAX_HASH_CHARS` (C/C++ users add one).
C/C++ users should add one to this value when allocating memory. 
The final digest will be truncated to the specified length if less than the expected size. 
MD2 is not available with the HMAC functions.

### Examples

```

Dim strData As String
Dim strKey As String
Dim abData() As Byte
Dim abKey() As Byte
Dim nDataLen As Long
Dim nKeyLen As Long
Dim strDigest As String
Dim nRet As Long

' Test case 2 from RFC 2202 and RFC 4231
strData = "what do ya want for nothing?"
strKey = "Jefe"

' Convert message and key into Byte format
abData = StrConv(strData, vbFromUnicode)
abKey = StrConv(strKey, vbFromUnicode)
nDataLen = UBound(abData) - LBound(abData) + 1
nKeyLen = UBound(abKey) - LBound(abKey) + 1

' Dimension the output string to receive the digest
strDigest = String(PKI_MAX_HASH_CHARS, " ")

' Compute default HMAC (HMAC-SHA-1)
nRet = HMAC_HexFromBytes(strDigest, Len(strDigest), abData(0), nDataLen, abKey(0), nKeyLen, 0)
If nRet <= 0 Then Exit Sub ' ERROR
strDigest = Left(strDigest, nRet)
Debug.Print "HMAC-SHA-1  =" & strDigest
Debug.Print "CORRECT     =" & "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79"

' Compute HMAC-MD5
strDigest = String(PKI_MAX_HASH_CHARS, " ")
nRet = HMAC_HexFromBytes(strDigest, Len(strDigest), abData(0), nDataLen, abKey(0), nKeyLen, PKI_HASH_MD5)
If nRet <= 0 Then Exit Sub ' ERROR
strDigest = Left(strDigest, nRet)
Debug.Print "HMAC-MD5    =" & strDigest
Debug.Print "CORRECT     =" & "750c783e6ab0b503eaa86e310a5db738"

' Compute HMAC-SHA-256
strDigest = String(PKI_MAX_HASH_CHARS, " ")
nRet = HMAC_HexFromBytes(strDigest, Len(strDigest), abData(0), nDataLen, abKey(0), nKeyLen, PKI_HASH_SHA256)
If nRet <= 0 Then Exit Sub ' ERROR
strDigest = Left(strDigest, nRet)
Debug.Print "HMAC-SHA-256=" & strDigest
Debug.Print "CORRECT     =" & "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843"

' Compute HMAC-SHA-512
strDigest = String(PKI_MAX_HASH_CHARS, " ")
nRet = HMAC_HexFromBytes(strDigest, Len(strDigest), abData(0), nDataLen, abKey(0), nKeyLen, PKI_HASH_SHA512)
If nRet <= 0 Then Exit Sub ' ERROR
strDigest = Left(strDigest, nRet)
Debug.Print "HMAC-SHA-512=" & strDigest
Debug.Print "CORRECT     =" _
& "164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea250554" _
& "9758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737" _

```

The above example should produce the following output:

```

HMAC-SHA-1  =effcdf6ae5eb2fa2d27416d5f184df9c259a7c79
CORRECT     =effcdf6ae5eb2fa2d27416d5f184df9c259a7c79
HMAC-MD5    =750c783e6ab0b503eaa86e310a5db738
CORRECT     =750c783e6ab0b503eaa86e310a5db738
HMAC-SHA-256=5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843
CORRECT     =5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843
HMAC-SHA-512=164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea250554
9758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737
CORRECT     =164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea250554
9758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737

```

### Example (VBA wrapper function)

```

Dim strDigest As String
Dim lpMessage() As Byte
Dim lpDigest() As Byte
Dim lpKey() As Byte
lpKey = cnvBytesFromHexStr("0102030405060708090a0b0c0d0e0f10111213141516171819")
lpDigest = hmacBytes(lpMessage, lpKey, PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)
lpDigest = hmacBytes(lpMessage, lpKey, PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)
strDigest = hmacHexFromBytes(lpMessage, lpKey, PKI_HASH_SHA256)
Debug.Print strDigest
strDigest = hmacHexFromBytes(lpMessage, lpKey, PKI_HASH_SHA512)
Debug.Print strDigest
strDigest = hmacHexFromBytes(lpMessage, lpKey, PKI_HASH_SHA512)
Debug.Print strDigest

```

### See Also

[HMAC_Bytes](#HMAC_Bytes)
[HMAC_HexFromHex](#HMAC_HexFromHex)

[[Contents](#topofpage)] [[Index](#index)]

<a id="HMAC_HexFromHex"></a>HMAC_HexFromHex
-------------------------------------------

Creates a keyed-hash based message authentication code (HMAC) 
 in hexadecimal format from data in hexadecimal-encoded strings.
The hash algorithm to use is passed in the options parameter.

### VBA/VB6 Syntax

`Public Declare Function HMAC_HexFromHex Lib "diCrPKI.dll" 
(ByVal strOutput As String, ByVal nOutChars As Long, 
ByVal strMsgHex As String, ByVal strKeyHex As String, ByVal nOptions As Long) As Long`

`nRet = HMAC_HexFromHex(strOutput, nOutChars, strMsgHex, strKeyHex, nOptions)`

### C/C++ Syntax

`long __stdcall HMAC_HexFromHex(char *szOutput, long nOutChars, const char *szMsgHex, const char *szKeyHex, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive output in hexadecimal format.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szMsgHex*
:   [in] containing the message data in hexadecimal-encoded format.

*szKeyHex*
:   [in] containing the key in hexadecimal-encoded format.

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_HASH_SHA1` (0) to use the SHA-1 algorithm (default)  

`PKI_HASH_SHA224` to use the SHA-224 algorithm  

`PKI_HASH_SHA256` to use the SHA-256 algorithm  

`PKI_HASH_SHA384` to use the SHA-384 algorithm  

`PKI_HASH_SHA512` to use the SHA-512 algorithm  

`PKI_HASH_SHA3_224` to use the SHA-3-224 algorithm  

`PKI_HASH_SHA3_256` to use the SHA-3-256 algorithm  

`PKI_HASH_SHA3_384` to use the SHA-3-384 algorithm  

`PKI_HASH_SHA3_512` to use the SHA-3-512 algorithm  

`PKI_HASH_MD5` to use the MD5 algorithm

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`hmacHexFromHex`](#VB_hmacHexFromHex) (szMsgHex As String, szKeyHex As String, nOptions As Long) As String

### .NET Equivalent

[Hmac.HexFromHex Method](#M_Hmac_HexFromHex)  

### C++ (STL) Equivalent

static std::string [dipki::Hmac::HexFromHex](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hmac.html#aedb10f9b3b1e3c29b10c39a4534fb60a "External link") (const std::string &dataHex, const std::string &keyHex, Alg alg=Alg::Sha1)

### Python Equivalent

static [Hmac.hex_from_hex](https://cryptosys.net/pki/pydocpki/class-stubs/Hmac.html#cryptosyspki.Hmac.hex_from_hex "External link")(datahex, keyhex, alg=Alg.SHA1)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The maximum number of output characters is `PKI_MAX_HASH_CHARS` (C/C++ users add one).
C/C++ users should add one to this value when allocating memory. 
The final digest will be truncated to the specified length if less than the expected size. 
MD2 is not available with the HMAC functions.

Note the order of parameters here (data, key) is different from the usual order HMAC(key, text).

### Example (VBA core function)

```

Dim strDigest As String
Dim nRet As Long
Dim strData As String
Dim strKey As String
' Ref: RFC 2202 and RFC 4231
' Test Case 1
' Key =  0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
'        0b0b0b0b                    (20 bytes)
' Data = 4869205468657265            ("Hi There")

' Compute HMAC-SHA-1
strDigest = String(PKI_SHA1_CHARS, " ")
strData = "4869205468657265"
strKey = "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"
nRet = HMAC_HexFromHex(strDigest, Len(strDigest), strData, strKey, PKI_HASH_SHA1)
Debug.Print strDigest
' Compute HMAC-SHA-256
strDigest = String(PKI_SHA256_CHARS, " ")
nRet = HMAC_HexFromHex(strDigest, Len(strDigest), strData, strKey, PKI_HASH_SHA256)
Debug.Print strDigest

```

The above example should produce the following output:

```

b617318655057264e28bc0b6fb378c8ef146be00
b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7

```

### Example (VBA wrapper function)

```

Dim lpData() As Byte
Dim lpKey() As Byte
Dim lpDigest() As Byte
Dim strDigest As String

' Test case 4 from RFC 2202 and RFC 4231
lpKey = cnvBytesFromHexStr("0102030405060708090a0b0c0d0e0f10111213141516171819")
' data = 0xcd repeated 50 times
lpData = cnvBytesFromHexStr("cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" & _
    "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd")
' Bytes <-- Bytes
lpDigest = hmacBytes(lpData, lpKey, PKI_HASH_SHA256)
Debug.Print "HMAC-SHA-256=" & cnvHexStrFromBytes(lpDigest)
Debug.Print "CORRECT     =82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b"
' Hex <-- Bytes
strDigest = hmacHexFromBytes(lpData, lpKey, PKI_HASH_SHA256)
Debug.Print "HMAC-SHA-256=" & strDigest

' Hex <-- Hex
' Test case 1 from RFC 2202 and RFC 4231
' Data = "Hi There"
strDigest = hmacHexFromHex("4869205468657265", "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", PKI_HASH_SHA256)
Debug.Print "HMAC-SHA-256=" & strDigest
Debug.Print "CORRECT     =b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"

```

### See Also

[HMAC_Bytes](#HMAC_Bytes)
[HMAC_HexFromBytes](#HMAC_HexFromBytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="HPKE_DerivePrivateKey"></a>HPKE_DerivePrivateKey
-------------------------------------------------------

Derive an EC private key in a deterministic manner from input keying material using the DeriveKeyPair algorithm in RFC9180.

### VBA/VB6 Syntax

`Public Declare Function HPKE_DerivePrivateKey Lib "diCrPKI.dll" (ByVal szOutput As String, ByVal nOutChars As Long, ByRef lpIkm As Byte, ByVal nIkmLen As Long, ByVal szCurveName As String, ByVal szParams As String, ByVal nOptions As Long) As Long`

`nRet = HPKE_DerivePrivateKey(szOutput, nOutChars, lpIkm(0), nIkmLen, szCurveName,, szParams, nOptions) ' Note the "(0)" after the byte array parameters`

### C/C++ Syntax

`long __stdcall HPKE_DerivePrivateKey(char *szOutput, long nOutChars, const unsigned char *lpIkm, long nIkmLen, const char *szCurveName, const char *szParams, long nOptions);`

### Parameters

*szOutput*
:   [out] string of sufficient length to receive the derived private key.

*nOutChars*
:   [in] maximum number of characters to be received.

*lpIkm*
:   [in] byte array containing the input key material (ikm). This *must* have length in bytes at least as long as the key to be produced.

*nIkmLen*
:   [in] length of the input key material in bytes.

*szCurveName*
:   [in] name of ECDH curve:
Specify one of:  

`"P-256"` |
`"P-384"` |
`"P-521"` |
`"X25519"` |
`"X448"`

*szParams*
:   [in] (optional) parameters. Not used in this version. Set as the empty string "".

*nOptions*
:   [in] Option flags. Select one of:  

Zero (0) to output the private key in ephemeral "internal" key format (default); or  

`PKI_ENCODE_HEX` to output the private key in serialized hex form.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string; otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`hpkeDerivePrivateKey`](#VB_hpkeDerivePrivateKey) (lpIkm() As Byte, szCurveName As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Hpke.DerivePrivateKey Method](#M_Hpke_DerivePrivateKey)  

### C++ (STL) Equivalent

static std::string [dipki::Hpke::DerivePrivateKey](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hpke.html#a5897999f600ef45d4c8da7217d712c5e "External link") (const bvec_t &ikm, CurveName curve, OutputOpts opts=OutputOpts::Default)

### Python Equivalent

static [Hpke.derive_private_key](https://cryptosys.net/pki/pydocpki/class-stubs/Hpke.html#cryptosyspki.Hpke.derive_private_key "External link")(ikm, curveName, opts=0)

### Remarks

By default the key is output as an ephemeral "internal" key string, which can be used directly with 
[`ECC_SaveKey`](#ECC_SaveKey),
[`ECC_SaveEncKey`](#ECC_SaveEncKey),
[`ECC_PublicKeyFromPrivate`](#ECC_PublicKeyFromPrivate),
[`ECC_DHSharedSecret`](#ECC_DHSharedSecret) and
[`ECC_QueryKey`](#ECC_QueryKey).
If *nOptions* is set to `PKI_ENCODE_HEX` then the key is output in serialized hexadecimal form in the same manner as the test vectors in [[RFC9180](#RFC9180)]
(without the clamping).

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

This function derives an ECDH private key in the deterministic manner described in [[RFC9180](#RFC9180)] using user-provided input key material (ikm).
There is *very, very* small chance that a valid key cannot be generated from the ikm; in which case the function will return a negative 
`KEYGEN_FAILED_ERROR` error code. 

The input key material *must* have length in bytes at least as long as the key to be produced (Nsk) or a `BAD_LENGTH_ERROR` error code will be returned.
The values of Nsk (the length in bytes of a Diffie-Hellman private key) for the supported EC curves are as follows:

| EC curve group | Nsk |
| --- | --- |
| P-256 | 32 |
| P-384 | 48 |
| P-521 | 66 |
| X25519 | 32 |
| X448 | 56 |

The KDF to be used is fixed by the EC curve group. See [Hybrid Public Key Encryption (HPKE)](#hybridpke).

### Example (VBA wrapper function)

```

Dim ikmhex As String
Dim skokhex As String
Dim pkokhex As String
Dim skhex As String
Dim pkhex As String
Dim prikeystr As String
Debug.Print "TESTING HPKE DERIVEPRIVATEKEY..."
Debug.Print "RFC9180 A.1. DHKEM(X25519, HKDF-SHA256)"
ikmhex = "7268600d403fce431561aef583ee1613527cff655c1343f29812e66706df3234"
skokhex = "52c4a758a802cd8b936eceea314432798d5baf2d7e9235dc084ab1b9cfa2f736"
pkokhex = "37fda3567bdbd628e88668c3c8d7e97d1d1253b6d4ea6d44c150f741f1bf4431"
' A. Derive private key in hex format
skhex = hpkeDerivePrivateKey(cnvFromHex(ikmhex), "X25519", PKI_ENCODE_HEX)
Debug.Print "skEm: " & skhex
' B. Derive key in ephemeral internal private key format (NB different each time)
prikeystr = hpkeDerivePrivateKey(cnvFromHex(ikmhex), "X25519")
' C. Get public key in hex format from internal key string
pkhex = eccQueryKey(prikeystr, "publicKey")
Debug.Print "pkEm: " & pkhex

```

```

skEm: 52c4a758a802cd8b936eceea314432798d5baf2d7e9235dc084ab1b9cfa2f736
pkEm: 37fda3567bdbd628e88668c3c8d7e97d1d1253b6d4ea6d44c150f741f1bf4431

```

### See Also

[[Contents](#topofpage)] [[Index](#index)]

<a id="HPKE_LabeledExpand"></a>HPKE_LabeledExpand
-------------------------------------------------

Compute the output of the LabeledExpand function as defined in RFC9180.

### VBA/VB6 Syntax

`Public Declare Function HPKE_LabeledExpand Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByRef lpPrk As Byte, ByVal nPrkLen As Long, ByVal szLabel As String, ByRef lpInfo As Byte, ByVal nInfoLen As Long, ByVal szCurveName As String, ByVal strParams As String, ByVal nOptions As Long) As Long`

`nRet = HPKE_LabeledExpand(lpOutput(0), nOutBytes, lpPrk(0), nPrkLen, szLabel, lpInfo(0), nInfoLen, szCurveName, szParams, nOptions) ' Note the "(0)" after the byte array parameters`

### C/C++ Syntax

`long __stdcall HPKE_LabeledExpand(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpPrk, long nPrkLen, const char *szLabel, const unsigned char *lpInfo, long nInfoLen,
	const char *szCurveName, const char *szParams, long nOptions);`

### Parameters

*lpOutput*
:   [out] byte array to be filled with output keying material.

*nOutputLen*
:   [in] required size of the output key in bytes (L).

*lpPrk*
:   [in] byte array containing the pseudorandom key (prk).

*nPrkLen*
:   [in] length of prk in bytes.

*szLabel*
:   [in] label string.

*lpInfo*
:   [in] byte array containing optional string info

*nInfoLen*
:   [in] length of info in bytes (can be zero)

*szCurveName*
:   [in] name of ECDH curve used in scheme (required):
Specify one of:  

`"P-256"` |
`"P-384"` |
`"P-521"` |
`"X25519"` |
`"X448"`

*szParams*
:   [in] (optional) parameters. Not used in this version. Set as the empty string "".

*nOptions*
:   [in] Option flags. Use to specify the AEAD encryption algorithm used in the scheme (if applicable).
Specify either:  

Zero (0) to indicate that the KDF is being used inside a KEM algorithm  

or, if used in the remainder of HPKE, one of:  

`PKI_AEAD_AES_128_GCM`  

`PKI_AEAD_AES_256_GCM`  

`PKI_AEAD_CHACHA20_POLY1305`

### Returns (VBA/C)

If successful, the return value is zero; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`hpkeLabeledExpand`](#VB_hpkeLabeledExpand) (nBytes As Long, lpPrk() As Byte, szLabel As String, lpInfo() As Byte, szCurveName As String, Optional nOptions As Long = 0) As Byte()

### .NET Equivalent

[Hpke.LabeledExpand Method](#M_Hpke_LabeledExpand)  

### C++ (STL) Equivalent

static bvec_t [dipki::Hpke::LabeledExpand](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hpke.html#a2fc65341143e165391f69aebf5950541 "External link") (int numBytes, const bvec_t &prk, std::string label, const bvec_t &info, CurveName curve, AeadAlg aeadAlg=AeadAlg::None)

### Python Equivalent

static [Hpke.labeled_expand](https://cryptosys.net/pki/pydocpki/class-stubs/Hpke.html#cryptosyspki.Hpke.labeled_expand "External link")(numbytes, prk, label, info, curveName, aeadalg=AeadAlg.NONE)

### Remarks

The output buffer for the output keying material *lpOutput* must exist and must have been dimensioned to at least the required length given in *nOutBytes*, which must be a positive number.
Note that the return value on success is *zero*. 

The `LabeledExpand` function is defined in section 4 of [[RFC9180](#RFC9180)]. It uses the "expand" stage of the HKDF function [[RFC5869](#RFC5869)]. 

Because this is a standalone function with no context, the ECDH curve group used in the scheme must be specified. 
This automatically fixes the KDF and associated HMAC algorithm to be used as per Table 2 of [[RFC9180](#RFC9180)].
In the case where the KDF is being used inside a KEM algorithm, the AEAD algorithm is not used and *nOptions* must be set to zero (0).
In the other case where the KDF is being used in the remainder of the HPKE scheme, an explicit AEAD algorithm must be specified in *nOptions*.
For more details see [Hybrid Public Key Encryption (HPKE)](#hybridpke).

### Example (VBA wrapper function)

```

Dim lpKey() As Byte
Dim lpPrk() As Byte
Dim lpInfo() As Byte
Dim Nk As Long
Debug.Print "RFC9180 Appendix A.1 DHKEM(X25519, HKDF-SHA256), HKDF-SHA256, AES-128-GCM"
Debug.Print "key = LabeledExpand(secret, 'key', key_schedule_context, Nk)"
Nk = 16
lpPrk = cnvFromHex("12fff91991e93b48de37e7daddb52981084bd8aa64289c3788471d9a9712f397")
lpInfo = cnvFromHex("00725611c9d98c07c03f60095cd32d400d8347d45ed67097bbad50fc56da742d07cb6cffde367bb0565ba28bb02c90744a20f5ef37f30523526106f637abb05449")
lpKey = hpkeLabeledExpand(Nk, lpPrk, "key", lpInfo, "X25519", PKI_AEAD_AES_128_GCM)
Debug.Print "key=" & cnvToHex(lpKey)
If cnvBytesLen(lpKey) = 0 Then Debug.Print errFormatErrorMessage()

```

```

key=4531685D41D65F03DC48F6B8302C05B0

```

### See Also

[HPKE_LabeledExtract](#HPKE_LabeledExtract)

[[Contents](#topofpage)] [[Index](#index)]

<a id="HPKE_LabeledExtract"></a>HPKE_LabeledExtract
---------------------------------------------------

Compute the output of the LabeledExtract function as defined in RFC9180. 

### VBA/VB6 Syntax

`Public Declare Function HPKE_LabeledExtract Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByRef lpSalt As Byte, ByVal nSaltLen As Long, ByVal strLabel As String, ByRef lpIkm As Byte, ByVal nIkmLen As Long, ByVal strCurveName As String, ByVal strParams As String, ByVal nOptions As Long) As Long`

`nRet = KDF_Bytes(lpOutput(0), nOutBytes, lpIKM(0), nIkmLen, lpInfo(0), nInfoLen, szParams, nOptions) ' Note the "(0)" after the byte array parameters`

### C/C++ Syntax

`long __stdcall HPKE_LabeledExtract(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpSalt, long nSaltLen, const char *szLabel, const unsigned char *lpIkm, long nIkmLen,
	const char *szCurveName, const char *szParams, long nOptions);`

### Parameters

*lpOutput*
:   [out] byte array to be filled with a pseudorandom key of fixed length.

*nOutputLen*
:   [in] length of the output array in bytes.

*lpSalt*
:   [in] byte array containing the optional salt.

*nSaltLen*
:   [in] length of salt in bytes (can be zero).

*szLabel*
:   [in] label string.

*lpIkm*
:   [in] byte array containing input keying material (ikm).

*nIkmLen*
:   [in] length of ikm in bytes.

*szCurveName*
:   [in] name of ECDH curve used in scheme (required):
Specify one of:  

`"P-256"` |
`"P-384"` |
`"P-521"` |
`"X25519"` |
`"X448"`

*szParams*
:   [in] (optional) parameters. Not used in this version. Set as the empty string "".

*nOptions*
:   [in] Option flags. Use to specify the AEAD encryption algorithm used in the scheme (if applicable).
Specify either:  

Zero (0) to indicate that the KDF is being used inside a KEM algorithm  

or, if used in the remainder of HPKE, one of:  

`PKI_AEAD_AES_128_GCM`  

`PKI_AEAD_AES_256_GCM`  

`PKI_AEAD_CHACHA20_POLY1305`

### Returns (VBA/C)

If successful, the return value is the number of bytes in or required for the output; otherwise it returns a negative [error code](#errorcodes).
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`hpkeLabeledExtract`](#VB_hpkeLabeledExtract) (lpSalt() As Byte, szLabel As String, lpIkm() As Byte, szCurveName As String, Optional nOptions As Long = 0) As Byte()

### .NET Equivalent

[Hpke.LabeledExtract Method](#M_Hpke_LabeledExtract)  

### C++ (STL) Equivalent

static bvec_t [dipki::Hpke::LabeledExtract](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hpke.html#a27d47d152488346f40b650cdf6063b88 "External link") (const bvec_t &salt, std::string label, const bvec_t &ikm, CurveName curve, AeadAlg aeadAlg=AeadAlg::None)

### Python Equivalent

static [Hpke.labeled_extract](https://cryptosys.net/pki/pydocpki/class-stubs/Hpke.html#cryptosyspki.Hpke.labeled_extract "External link")(salt, label, ikm, curveName, aeadalg=AeadAlg.NONE)

### Remarks

The `LabeledExtract` function is defined in section 4 of [[RFC9180](#RFC9180)]. It uses the "extract" stage of the HKDF function [[RFC5869](#RFC5869)]. 
It outputs a fixed value of bytes equal to the length (Nh) of the underlying HMAC function used by the KDF algorithm.

Because this is a standalone function with no context, the ECDH curve group used in the scheme must be specified. 
This automatically fixes the KDF and associated HMAC algorithm to be used as per Table 2 of [[RFC9180](#RFC9180)].
In the case where the KDF is being used inside a KEM algorithm, the AEAD algorithm is not used and *nOptions* must be set to zero (0).
In the other case where the KDF is being used in the remainder of the HPKE scheme, an explicit AEAD algorithm must be specified in *nOptions*.
For more details see [Hybrid Public Key Encryption (HPKE)](#hybridpke).

### Example (VBA wrapper function)

```

Dim lpExtracted() As Byte
Dim lpSalt() As Byte
Dim lpIkm() As Byte
Debug.Print "RFC9180 Appendix A.1 DHKEM(X25519, HKDF-SHA256), HKDF-SHA256, AES-128-GCM"
Debug.Print "prk = LabeledExtract('', 'dkp_prk', ikm)"
lpSalt = vbNullString
lpIkm = cnvFromHex("7268600d403fce431561aef583ee1613527cff655c1343f29812e66706df3234")
lpExtracted = hpkeLabeledExtract(lpSalt, "dkp_prk", lpIkm, "X25519")
Debug.Print "prk=" & cnvToHex(lpExtracted)
If cnvBytesLen(lpExtracted) = 0 Then Debug.Print errFormatErrorMessage()

```

```

prk=7B8BFE1D6F3D0CB45C585E133299C64AC998BF46CAF2DC13BA874F23413EC23A

```

### See Also

[HPKE_LabeledExpand](#HPKE_LabeledExpand)

[[Contents](#topofpage)] [[Index](#index)]

<a id="KDF_Bytes"></a>KDF_Bytes
-------------------------------

Generate a key-encryption key (KEK) from input keying material using a key derivation function (KDF).

### VBA/VB6 Syntax

`Public Declare Function KDF_Bytes Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByRef lpIKM As Byte, ByVal nIkmLen As Long, ByRef lpInfo As Byte, ByVal nInfoLen As Long, ByVal szParams As String, ByVal nOptions As Long) As Long`

`nRet = KDF_Bytes(lpOutput(0), nOutBytes, lpIKM(0), nIkmLen, lpInfo(0), nInfoLen, szParams, nOptions) ' Note the "(0)" after the byte array parameters`

### C/C++ Syntax

`long __stdcall KDF_Bytes(unsigned char *lpOutput, long nOutBytes, const void *lpIKM, long nIkmLen, const void *lpInfo, long nInfoLen, const char *szParams, long nOptions);`

### Parameters

*lpOutput*
:   [out] byte array to be filled with output key material (OKM/KEK) (cannot be NULL).

*nOutputLen*
:   [in] required size of the output key in bytes (must be greater than zero).

*lpIKM*
:   [in] byte array containing the input key material/shared secret value (denoted variously as IKM/K/Z/ZZ).

*nIkmLen*
:   [in] length of the input key material in bytes.

*lpInfo*
:   [in] byte array containing the optional SharedInfo (otherInfo/key derivation parameter/kdp).

*nInfoLen*
:   [in] length of the SharedInfo in bytes.

*szParams*
:   [in] (optional) parameters. Set as the empty string `""` for defaults. 
	Otherwise include a set of attribute-value pairs separated by a semi-colon ";" to set options from the following
* `salt=<hex-digits>` to set the optional salt parameter for the HKDF algorithm encoded in hex format,
	e.g. `"salt=606162636465666768696a6b6c6d6e6f;"` [default=no salt]

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_KDF_X963` to use the the ANSI-X9.63-KDF key derivation function (default)  

`PKI_KDF_HKDF` to use the HMAC-based Key Derivation Function (HKDF) from RFC 5869  

`PKI_KDF_KDF2` to use KDF2 from ANSI-X9.44. *New in [v23.0]*  

`PKI_KDF_KDF3` to use KDF3 from ANSI-X9.44. *New in [v23.0]*  

and select one hash algorithm to use with the key derivation function:  

`PKI_HASH_SHA1` (0) to use the SHA-1 hash algorithm (default - CAUTION)  

`PKI_HASH_SHA224` to use the SHA-224 algorithm  

`PKI_HASH_SHA256` to use the SHA-256 algorithm [minimum recommended]  

`PKI_HASH_SHA384` to use the SHA-384 algorithm  

`PKI_HASH_SHA512` to use the SHA-512 algorithm

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`kdfBytes`](#VB_kdfBytes) (nKekBytes As Long, lpIkm() As Byte, lpInfo() As Byte, Optional nOptions As Long = 0, Optional szParams As String = "") As Byte()

### .NET Equivalent

[Kdf.Bytes Method](#M_Kdf_Bytes)  

### C++ (STL) Equivalent

static bvec_t [dipki::Kdf::Bytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_kdf.html#ad3196c7ce3cf9588c27782d2c1e7ede9 "External link") (int dklen, const bvec_t &ikm, KdfAlg kdfAlg=KdfAlg::X963, HashAlg hashAlg=HashAlg::Sha1, const bvec_t &sharedInfo={}, const std::string &paramString="")

### Python Equivalent

static [Kdf.bytes](https://cryptosys.net/pki/pydocpki/class-stubs/Kdf.html#cryptosyspki.Kdf.bytes "External link")(dklen, ikm, kdfalg, hashalg=HashAlg.SHA1, sharedinfo=None, paramstring="")

### Remarks

The output buffer for the output key material *lpOutput* must exist and must have been dimensioned to at least the required length given in *nOutBytes*, which must be a positive number.
Note that the return value on success is *zero*. 

The ANSI-X9.63-KDF key derivation function is described in section 3.6.1 of [[SEC1](#SEC1)].
The HMAC-based Key Derivation Function (HKDF) is described in [[RFC5869](#RFC5869)].
KDF2 and KDF3 are described in ANSI X9.44 [[X9-44](#X9-44)].

### Example (VBA core function)

```

Dim nBytes As Long
Dim lpOutput() As Byte
Dim lpZZ() As Byte
Dim lpInfo() As Byte
Dim r As Long

' ansx963_2001.rsp
' # CAVS 12.0
' # 'ANS X9.63-2001' information for sample
' [SHA-256]
' [shared secret length = 192]
' [SharedInfo length = 0]
' [key data length = 128]
' COUNT = 0
' Z = 96c05619d56c328ab95fe84b18264b08725b85e33fd34f08
' SharedInfo =
' key_data = 443024c3dae66b95e6f5670601558f71
nBytes = 128 \ 8
ReDim lpOutput(nBytes - 1)
lpZZ = cnvFromHex("96c05619d56c328ab95fe84b18264b08725b85e33fd34f08")
r = KDF_Bytes(lpOutput(0), nBytes, lpZZ(0), cnvBytesLen(lpZZ), ByVal 0&, 0, "", PKI_KDF_X963 Or PKI_HASH_SHA256)
Debug.Print "KDF_Bytes returns " & r
Debug.Print "KEK=" & cnvToHex(lpOutput)
Debug.Print "OK =" & "443024c3dae66b95e6f5670601558f71"

' [RFC 5869] A.1.  Test Case 1 Basic test case with SHA-256
nBytes = 42
ReDim lpOutput(nBytes - 1)
lpZZ = cnvFromHex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b")   ' 22 octets
lpInfo = cnvFromHex("f0f1f2f3f4f5f6f7f8f9")  ' 10 octets
r = KDF_Bytes(lpOutput(0), nBytes, lpZZ(0), cnvBytesLen(lpZZ), lpInfo(0), cnvBytesLen(lpInfo), "salt=000102030405060708090a0b0c", PKI_KDF_HKDF Or PKI_HASH_SHA256)
Debug.Print "KDF_Bytes returns " & r
Debug.Print "KEK=" & cnvToHex(lpOutput)
Debug.Print "OK =" & "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"

```

```

KDF_Bytes returns 0
KEK=443024C3DAE66B95E6F5670601558F71
OK =443024c3dae66b95e6f5670601558f71
KDF_Bytes returns 0
KEK=3CB25F25FAACD57A90434F64D0362F2A2D2D0A90CF1A5A4C5DB02D56ECC4C5BF34007208D5B887185865
OK =3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865

```

### Example (VBA wrapper function)

```

Dim lpKEK() As Byte
Dim lpZZ() As Byte
Dim lpInfo() As Byte

' ansx963_2001.rsp CAVS 12.0 'ANS X9.63-2001' information for sample
lpZZ = cnvFromHex("96c05619d56c328ab95fe84b18264b08725b85e33fd34f08")
lpKEK = kdfBytes(128 \ 8, lpZZ, lpInfo, PKI_HASH_SHA256)
Debug.Print "KEK = " & cnvHexStrFromBytes(lpKEK)
Debug.Print "OK  = 443024c3dae66b95e6f5670601558f71"

' [RFC 5869] A.1.  Test Case 1 Basic test case with SHA-256
lpZZ = cnvFromHex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b")
lpInfo = cnvFromHex("f0f1f2f3f4f5f6f7f8f9")
lpKEK = kdfBytes(42, lpZZ, lpInfo, PKI_KDF_HKDF Or PKI_HASH_SHA256, "salt=000102030405060708090a0b0c")
Debug.Print "KEK = " & cnvHexStrFromBytes(lpKEK)
Debug.Print "OK  = 3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"

```

### See Also

[KDF_ForCms](#KDF_ForCms)

[[Contents](#topofpage)] [[Index](#index)]

<a id="KDF_ForCms"></a>KDF_ForCms
---------------------------------

Generate a key-encryption key (KEK) for ECDH key exchange in a CMS EnvelopedData object.

### VBA/VB6 Syntax

`Public Declare Function KDF_ForCms Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByRef lpZZ As Byte, ByVal nZzLen As Long, ByRef lpUkm As Byte, ByVal nUkmLen As Long, ByVal szParams As String, ByVal nOptions As Long) As Long`

`nRet = KDF_ForCms(lpOutput(0), nOutBytes, lpZZ(0), nZzLen, lpUkm(0), nUkmLen, szParams, nOptions) ' Note the "(0)" after the byte array parameters`

### C/C++ Syntax

`long __stdcall KDF_ForCms(unsigned char *lpOutput, long nOutBytes, const void *lpZZ, long nZzLen, const void *lpUkm, long nUkmLen, const char *szParams, long nOptions);`

### Parameters

*lpOutput*
:   [out] byte array to be filled with output key material (OKM/KEK).

*nOutputLen*
:   [in] required size of the output key in bytes.

*lpZZ*
:   [in] byte array containing the input key material/shared secret value (denoted variously as ZZ/Z/K/IKM).

*nZzLen*
:   [in] length of the shared secret material in bytes.

*lpUkm*
:   [in] (optional) byte array containing user key material (ukm)

*nUkmLen*
:   [in] length of user key material (ukm) in bytes.

*szParams*
:   [in] (optional) parameters. Not used in this version. Set as the empty string "".

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_KDF_X963` to use the the ANSI-X9.63-KDF key derivation function (default) or  

`PKI_KDF_HKDF` to use the HMAC-based Key Derivation Function (HKDF) from RFC 5869;  

and select one hash algorithm to use with the key derivation function:  

`PKI_HASH_SHA1` (0) to use the SHA-1 hash algorithm (default)  

`PKI_HASH_SHA224` to use the SHA-224 algorithm  

`PKI_HASH_SHA256` to use the SHA-256 algorithm [minimum recommended]  

`PKI_HASH_SHA384` to use the SHA-384 algorithm  

`PKI_HASH_SHA512` to use the SHA-512 algorithm  

and select one option to specify the key wrap algorithm (no default):  

`PKI_KWRAP_3DES` to use `cms3DESwrap`  

`PKI_KWRAP_AES128` to use `aes128-wrap`  

`PKI_KWRAP_AES192` to use `aes192-wrap`  

`PKI_KWRAP_AES256` to use `aes256-wrap`

### Returns (VBA/C)

If successful, the return value is the number of bytes in or required for the output key material;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`kdfForCms`](#VB_kdfForCms) (lpZZ() As Byte, lpUkm() As Byte, Optional nOptions As Long = 0) As Byte()

### .NET Equivalent

[Kdf.ForCms Method](#M_Kdf_ForCms)  

### C++ (STL) Equivalent

static bvec_t [dipki::Kdf::ForCms](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_kdf.html#a646a8ea8e026b47e4177950ccfe2159a "External link") (const bvec_t &zz, KeyWrapAlg keyWrapAlg, KdfAlg kdfAlg=KdfAlg::X963, HashAlg hashAlg=HashAlg::Sha1, const bvec_t &ukm={})

### Python Equivalent

static [Kdf.for_cms](https://cryptosys.net/pki/pydocpki/class-stubs/Kdf.html#cryptosyspki.Kdf.for_cms "External link")(zz, keywrapalg, kdfalg=KdfAlg.X963, hashalg=HashAlg.SHA1, ukm=None)

### Remarks

This is a specialist function using the key definition algorithms described in [[RFC5753](#RFC5753)] and [[RFC8418](#RFC8418)] when used for key agreement with ECDH in a CMS EnvelopedData object using the ECC-CMS-SharedInfo structure. 

Note the behaviour of this function is different from `KDF_KeyBytes` as the length of the output is fixed by the key wrap algorithm and is not an arbitrary number.
The function returns the number of bytes in the output key material, not zero on success.
Specify a zero *nOutChars* or `NULL` for *szOutput* to find the required number of bytes for the given key wrap algorithm. 
The output buffer for the output key material *lpOutput* must have been dimensioned to at least the required length in *nOutBytes*.

When using ECDH with EnvelopedData, the key-encryption keys are derived using the ECC-CMS-SharedInfo type, described in section 7.2 of [[RFC5753](#RFC5753)]
(the SharedInfo input to the KDF is the DER-encoded ECC-CMS-SharedInfo structure).

The processing of the ukm with the HKDF key derivation function is described in section 2.2 of [[RFC8418](#RFC8418)]
(TL;DR if provided, the ukm is included in the entityUInfo field of the ECC-CMS-SharedInfo structure *and* is used as the salt, otherwise no salt is provided).

### Example (VBA core function)

```

Dim nBytes As Long
Dim lpOutput() As Byte
Dim lpZZ() As Byte
Dim lpUkm() As Byte

lpZZ = cnvFromHex("160E3F5588C6FB4E9CEE8BC3C1C5000AB86396468C3D1CAEC0CB6E21536B5513")
' How many bytes for specified key wrap algorithm?
nBytes = KDF_ForCms(ByVal 0&, 0, lpZZ(0), cnvBytesLen(lpZZ), ByVal 0&, 0, "", PKI_KWRAP_AES128 Or PKI_KDF_X963 Or PKI_HASH_SHA1)
Debug.Print "KDF_ForCms returns " & nBytes
Debug.Assert (nBytes > 0)
ReDim lpOutput(nBytes - 1)
nBytes = KDF_ForCms(lpOutput(0), nBytes, lpZZ(0), cnvBytesLen(lpZZ), ByVal 0&, 0, "", PKI_KWRAP_AES128 Or PKI_KDF_X963 Or PKI_HASH_SHA1)
Debug.Print "KEK=" & cnvToHex(lpOutput)
Debug.Print "OK =" & "04D616C654CDF62BB186A5A088B60FB5"

lpUkm = cnvFromHex("616263")    ' "abc"
nBytes = KDF_ForCms(ByVal 0&, 0, lpZZ(0), cnvBytesLen(lpZZ), lpUkm(0), cnvBytesLen(lpUkm), "", PKI_KWRAP_AES256 Or PKI_KDF_HKDF Or PKI_HASH_SHA256)
Debug.Print "KDF_ForCms returns " & nBytes
Debug.Assert (nBytes > 0)
ReDim lpOutput(nBytes - 1)
nBytes = KDF_ForCms(lpOutput(0), nBytes, lpZZ(0), cnvBytesLen(lpZZ), lpUkm(0), cnvBytesLen(lpUkm), "", PKI_KWRAP_AES256 Or PKI_KDF_HKDF Or PKI_HASH_SHA256)
Debug.Print "KEK=" & cnvToHex(lpOutput)
Debug.Print "OK =" & "1D06D6FD5C1EBFB33CAD875E6B99781D3D750875F573C9093CECBFBA6937ACC5"

```

```

KDF_ForCms returns 16
KEK=04D616C654CDF62BB186A5A088B60FB5
OK =04D616C654CDF62BB186A5A088B60FB5
KDF_ForCms returns 32
KEK=1D06D6FD5C1EBFB33CAD875E6B99781D3D750875F573C9093CECBFBA6937ACC5
OK =1D06D6FD5C1EBFB33CAD875E6B99781D3D750875F573C9093CECBFBA6937ACC5

```

### Example (VBA wrapper function)

```

Dim lpKEK() As Byte
Dim lpZZ() As Byte
Dim lpUkm() As Byte

lpZZ = cnvFromHex("160E3F5588C6FB4E9CEE8BC3C1C5000AB86396468C3D1CAEC0CB6E21536B5513")
lpKEK = kdfForCms(lpZZ, lpUkm, PKI_KWRAP_AES128 Or PKI_KDF_X963 Or PKI_HASH_SHA1)
Debug.Print "KEK = " & cnvHexStrFromBytes(lpKEK)
Debug.Print "OK  = 04D616C654CDF62BB186A5A088B60FB5"

lpUkm = cnvFromHex("616263")    ' "abc"
lpKEK = kdfForCms(lpZZ, lpUkm, PKI_KWRAP_AES256 Or PKI_KDF_HKDF Or PKI_HASH_SHA256)
Debug.Print "KEK = " & cnvHexStrFromBytes(lpKEK)
Debug.Print "OK  = 1D06D6FD5C1EBFB33CAD875E6B99781D3D750875F573C9093CECBFBA6937ACC5"

```

### See Also

[KDF_Bytes](#KDF_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="OCSP_MakeRequest"></a>OCSP_MakeRequest
---------------------------------------------

Creates an Online Certification Status Protocol (OCSP) request as a base64 string.

### VBA/VB6 Syntax

`Public Declare Function OCSP_MakeRequest Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strIssuerCert As String, ByVal strCertFileOrSerialNum As String, ByVal strExtensions As String, ByVal nOptions As Long) As Long`

`nRet = OCSP_MakeRequest(strOutput, nOutChars, strIssuerCert, strCertFileOrSerialNum, strExtensions, nOptions)`

### C/C++ Syntax

`long __stdcall OCSP_MakeRequest(char *szOutput, long nOutChars, const char *szIssuerCert, const char *szCertFileOrSerialNum, const char *szExtensions, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive output in base64 format.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szIssuerCert*
:   [in] with name of issuer's X.509 certificate file (or [base64 representation](#base64forcert)).

*szCertFileOrSerialNum*
:   [in]  with either the name of X.509 certificate file to be checked 
or its serial number in hexadecimal format preceded by "#x".

*szExtensions*
:   [in] Not used. Set as empty string `""` or NULL.

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_HASH_SHA1` (0) to use the SHA-1 algorithm (default)  

`PKI_HASH_SHA224` to use the SHA-224 algorithm  

`PKI_HASH_SHA256` to use the SHA-256 algorithm  

`PKI_HASH_SHA384` to use the SHA-384 algorithm  

`PKI_HASH_SHA512` to use the SHA-512 algorithm  

`PKI_HASH_MD5` to use the MD5 algorithm

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`ocspMakeRequest`](#VB_ocspMakeRequest) (szIssuerCert As String, szCertFileOrSerialNum As String, nOptions As Long, Optional szExtensions As String = "") As String

### .NET Equivalent

[Ocsp.MakeRequest Method](#M_Ocsp_MakeRequest)  

### C++ (STL) Equivalent

static std::string [dipki::Ocsp::MakeRequest](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ocsp.html#af639efb0c08004ee072481faa28393ac "External link") (const std::string &issuerCert, const std::string &certFileOrSerialNumber, HashAlg hashAlg=HashAlg::Sha1)

### Python Equivalent

static [Ocsp.make_request](https://cryptosys.net/pki/pydocpki/class-stubs/Ocsp.html#cryptosyspki.Ocsp.make_request "External link")(issuercert, certfile_or_serialnumber, hashalg=0)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The output is a base64 string suitable for an OCSP request to an Online Certificate Status Manager. 
The issuer's X.509 certficate must be specified. The certificate to be checked
can either be specified directly as a filename or as a serialNumber in hexadecimal format preceded by "#x", e.g. 
`"#x01deadbeef"`. 
If the latter format is used, it must be in hexadecimal format, so the serial number 10 would be passed as
`"#x0a"`.
It is an error (`NO_MATCH_ERROR`) if the issuer's name of the certificate to be checked 
does not match the subject name of the issuer's certificate. 
The default hash algorithm is SHA-1. Most Online Certificate Status Managers should accept MD5 and SHA-1. 
Other hash algorithms may not be accepted.

One way to obtain a response is to paste the URL in the address bar of a web browser to return the status information.
The base64 value produced by this function should first be URL-encoded 
(i.e. "/" replaced by "%2F",  "+" replaced by "%2B", and "=" by "%3D"). 
For example, typing in the Firefox browser URL box

```

http://ocsp.comodoca.com/MFIwUDBOMEwwSjAJBgUrDgMCGgUABBRtl6lMY2%2BiPob4twryIF%2BFfgUdvwQUK8NGq7oOyWUqRtF5R8Ri4uHa%2FLgCEQD7xyMijIyAItiFkiPe5wZg

```

should offer to save a file with a name like 
`MFIwUDBOME...`. 
This contains the response, which is a binary file that can be examined using the 
[OCSP_ReadResponse()](#OCSP_ReadResponse) function.

### Example (VBA core function)

This example creates an OCSP request to check our own (old but never revoked) code signing certificate file `dims.cer`. 
This was issued by the holder of certificate in the file `UTNUSERFirst-Object.cer`.

```

Dim nChars As Long
Dim strCertFile As String
Dim strIssuerFile As String
Dim strBuf As String

strIssuerFile = "UTNUSERFirst-Object.cer"
strCertFile = "dims.cer"

Debug.Print "IssuerFile=" & strIssuerFile
Debug.Print "CertFile=" & strCertFile
' Find required length (or error)
nChars = OCSP_MakeRequest("", 0, strIssuerFile, strCertFile, "", 0)
Debug.Print "OCSP_MakeRequest returns " & nChars & "(expected +ve)"
If (nChars <= 0) Then Exit Sub   ' ERROR
strBuf = String(nChars, " ")
nChars = OCSP_MakeRequest(strBuf, nChars, strIssuerFile, strCertFile, "", 0)
Debug.Print "OCSPRequest=" & strBuf

' Pass a hex serial number instead of filename
strCertFile = "#x 00 FB C7 23 22 8C 8C 80 22 D8 85 92 23 DE E7 06 60"
Debug.Print "Cert SerialNumber=" & strCertFile
nChars = OCSP_MakeRequest("", 0, strIssuerFile, strCertFile, "", 0)
Debug.Print "OCSP_MakeRequest returns " & nChars & "(expected +ve)"
If (nChars <= 0) Then Exit Sub   ' ERROR
strBuf = String(nChars, " ")
nChars = OCSP_MakeRequest(strBuf, nChars, strIssuerFile, strCertFile, "", 0)
Debug.Print "OCSPRequest=" & strBuf

```

The above example should produce the following output:

```

IssuerFile=UTNUSERFirst-Object.cer
CertFile=dims.cer
OCSP_MakeRequest returns 112(expected +ve)
OCSPRequest=MFIwUDBOMEwwSjAJBgUrDgMCGgUABBRtl6lMY2+iPob4twryIF+FfgUdvwQUK8NGq7oOyWUqRtF5R8Ri4uHa/LgCEQD7xyMijIyAItiFkiPe5wZg
Cert SerialNumber=#x 00 FB C7 23 22 8C 8C 80 22 D8 85 92 23 DE E7 06 60
OCSP_MakeRequest returns 112(expected +ve)
OCSPRequest=MFIwUDBOMEwwSjAJBgUrDgMCGgUABBRtl6lMY2+iPob4twryIF+FfgUdvwQUK8NGq7oOyWUqRtF5R8Ri4uHa/LgCEQD7xyMijIyAItiFkiPe5wZg

```

### Example (VBA wrapper function)

```

Dim strOcsp As String
strOcsp = ocspMakeRequest("UTNUSERFirst-Object.cer", "dims.cer", PKI_HASH_SHA1)
Debug.Print strOcsp
' Pass serial number instead of filename
strOcsp = ocspMakeRequest("UTNUSERFirst-Object.cer", "#x 00 FB C7 23 22 8C 8C 80 22 D8 85 92 23 DE E7 06 60", PKI_HASH_SHA1)
Debug.Print strOcsp
```

### See Also

[OCSP_ReadResponse](#OCSP_ReadResponse)

[[Contents](#topofpage)] [[Index](#index)]

<a id="OCSP_ReadResponse"></a>OCSP_ReadResponse
-----------------------------------------------

Reads a response to an Online Certification Status Protocol (OCSP) request and outputs the main results in text form.

### VBA/VB6 Syntax

`Public Declare Function OCSP_ReadResponse Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strResponseFile As String, ByVal strIssuerCert As String, ByVal strExtensions As String, ByVal nOptions As Long) As Long`

`nRet = OCSP_ReadResponse(strOutput, nOutChars, strResponseFile, strIssuerCert, strExtensions, nOptions)`

### C/C++ Syntax

`long __stdcall OCSP_ReadResponse(char *szOutput, long nOutChars, const char *szResponseFile, const char *szIssuerCert, const char *szExtensions, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive output as ordinary text.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szResponseFile*
:   [in] with the name of the file containing the response data in BER format.

*szIssuerCert*
:   [in] (optional) with name of issuer's X.509 certificate file (or [base64 representation](#base64forcert)).

*szExtensions*
:   [in] Not used. Set as empty string `""` or NULL.

*nOptions*
:   [in] Option flags. For future use. Specify zero.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`ocspReadResponse`](#VB_ocspReadResponse) (szResponseFile As String, Optional szIssuerCert As String = "", Optional nOptions As Long = 0, Optional szExtensions As String = "") As String

### .NET Equivalent

[Ocsp.ReadResponse Method](#M_Ocsp_ReadResponse)  

### C++ (STL) Equivalent

static std::string [dipki::Ocsp::ReadResponse](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ocsp.html#a0e078b975897cfd0433904c61959dc76 "External link") (const std::string &responseFile, const std::string &issuerCert="")

### Python Equivalent

static [Ocsp.read_response](https://cryptosys.net/pki/pydocpki/class-stubs/Ocsp.html#cryptosyspki.Ocsp.read_response "External link")(responsefile, issuercert="")

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The output is a text string outlining the main results in the response data. Typical result strings are:

```

Successful response:
 Produced at 2010-03-18T00:09:28Z
 CertStatus=good
 SerialNumber=00FBC723228C8C8022D8859223DEE70660

```

```

Successful response:
 Produced at 2010-03-27T12:13:11Z
 CertStatus=revoked at 2009-05-29T19:23:16Z
 SerialNumber=7FFED5D77FD1AEEC63716CA220B098A9

```

```

malformedRequest.

```

```

unauthorized.

```

Note that a revoked certificate will still result in a "Successful response".

 
The issuer's X.509 certficate *szIssuerCert* is optional. If provided, it will be used to check the signature on the OCSP reponse and
and an error will result if the signature is not valid.
**CAUTION:** For some CAs (e.g. VeriSign) the key used to sign the OCSP response is not the same as the key in the issuer's certificate,
so specifying the issuer's certificate in this case will result in a signature error.
If you can separately obtain the certificate used to sign the OCSP response, then specify this as the *szIssuerCert*;
otherwise leave as the empty string `""`.

### Example (VBA core function)

```

Dim nChars As Long
Dim strResponseFile As String
Dim strIssuerFile As String
Dim strBuf As String
strResponseFile = "ocsp_response_ok_dims.dat"
strIssuerFile = "UTNUSERFirst-Object.cer"
Debug.Print "ResponseFile=" & strResponseFile
Debug.Print "IssuerFile=" & strIssuerFile
nChars = OCSP_ReadResponse("", 0, strResponseFile, strIssuerFile, "", 0)
Debug.Print "OCSP_ReadResponse returns " & nChars & " (expected +ve)"
If (nChars <= 0) Then Exit Sub   ' ERROR
strBuf = String(nChars, " ")
nChars = OCSP_ReadResponse(strBuf, nChars, strResponseFile, strIssuerFile, "", 0)
Debug.Print "OCSPResponse=" & strBuf

```

The above example using a response received from ocsp.usertrust.com for our own (old but never revoked) code signing certificate
produced the following output:

```

ResponseFile=ocsp_response_ok_dims.dat
IssuerFile=UTNUSERFirst-Object.cer
OCSP_ReadResponse returns 120 (expected +ve)
OCSPResponse=Successful response:
 Produced at 2010-03-18T00:09:28Z
 CertStatus=good
 SerialNumber=00FBC723228C8C8022D8859223DEE70660	

```

### Example (VBA wrapper function)

```

Dim strBuf As String
strBuf = ocspReadResponse("ocsp_response_ok_dims.dat", "UTNUSERFirst-Object.cer")
Debug.Print strBuf
```

### See Also

[OCSP_MakeRequest](#OCSP_MakeRequest)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PAD_BytesBlock"></a>PAD_BytesBlock
-----------------------------------------

Creates an input block suitably padded for encryption by a block cipher in ECB or CBC mode. 

### VBA/VB6 Syntax

`Public Declare Function PAD_BytesBlock Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutputLen As Long, ByRef lpInput As Byte, ByVal nInputLen As Long, ByVal nBlockLen As Long, ByVal nOptions As Long) As Long`

`nRet = PAD_BytesBlock(lpOutput(0), nOutputLen, lpInput(0), nInputLen, nBlockLen, nOptions) ' Note the "(0)" after the byte array parameters`

### C/C++ Syntax

`long __stdcall PAD_BytesBlock(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpInput, long nInputLen, long nBlkLen, long nOptions);`

### Parameters

*lpOutput*
:   [out] array to be filled with padded encryption block.

*nOutBytes*
:   [in] specifying the size of the output array in bytes.

*lpInput*
:   [in] array containing the plaintext bytes to be padded.

*nInputLen*
:   [in] specifying the length of the plaintext in bytes.

*nBlkLen*
:   [in] specifying the cipher block length in bytes (8 or 16).

*nOptions*
:   [in] option flags. Select one of:  

`PKI_PAD_DEFAULT` (0) to use the default PKCS5 padding  

`PKI_PAD_PKCS5` to use Pkcs5Padding (same as default)  

`PKI_PAD_1ZERO` to use OneAndZeroesPadding  

`PKI_PAD_AX923` to use the padding scheme described in ANSI X9.23  

`PKI_PAD_W3C` to use the padding scheme described in W3C <https://www.w3.org/TR/xmlenc-core1/#sec-Padding>

### Returns (VBA/C)

If successful, the return value is the number of bytes in the output;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`padBytesBlock`](#VB_padBytesBlock) (lpInput() As Byte, nBlkLen As Long, Optional nOptions As Long = 0) As Byte()

### .NET Equivalent

[Cipher.Pad Method](#M_Cipher_Pad_ByteCipherAlgorithmPadding)  

### C++ (STL) Equivalent

static bvec_t [dipki::Cipher::Pad](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#a9c5ae708169fffeb46129fa955faf200 "External link") (const bvec_t &input, Alg alg, Padding pad=Padding::Pkcs5)

### Python Equivalent

static [Cipher.pad](https://cryptosys.net/pki/pydocpki/class-stubs/Cipher.html#cryptosyspki.Cipher.pad "External link")(data, alg, pad=Pad.PKCS5)

### Remarks

The output will be padded according to the convention specified. 
If *nOutBytes* is set to zero or *lpOutput* set to 0 (or `NULL` in C or `ByVal 0&` in VBA)
then the required number of bytes will be returned. The output is *always* longer than the input.
Only block lengths of 8 or 16 bytes are supported.

### Example (VBA core function)

Note the test when unpadding to cope with a zero-length byte array.

```

Dim abInput() As Byte
Dim abOutput() As Byte
Dim nOutputLen As Long
Dim nInputLen As Long
Dim nBlockLen As Long
Dim i As Long

' Prepare test input 5 bytes long
nInputLen = 5
ReDim abInput(nInputLen - 1)
For i = 0 To nInputLen - 1
    abInput(i) = &HFF
Next
Debug.Print "Input data=0x" & cnvHexStrFromBytes(abInput)

' Find out the required length
nBlockLen = 8
nOutputLen = PAD_BytesBlock(vbNull, 0, abInput(0), nInputLen, nBlockLen, 0)
Debug.Print "Required length is " & nOutputLen & " bytes"
' Check for error
If (nOutputLen <= 0) Then Exit Function

' Pre-dimension output
ReDim abOutput(nOutputLen - 1)

nOutputLen = PAD_BytesBlock(abOutput(0), nOutputLen, abInput(0), nInputLen, nBlockLen, 0)
Debug.Print "Padded data=0x" & cnvHexStrFromBytes(abOutput)

' Now set input as padded output and remove padding
abInput = abOutput
nInputLen = nOutputLen

' Remove padding...
' No need to query for length because we know the output will be shorter than input
' so make sure output is as long as the input
nOutputLen = nInputLen
ReDim abOutput(nOutputLen - 1)
nOutputLen = PAD_UnpadBytes(abOutput(0), nOutputLen, abInput(0), nInputLen, nBlockLen, 0)
Debug.Print "Unpadded length is " & nOutputLen & " bytes"
' Check for error
If (nOutputLen < 0) Then Exit Function
' Truncate the output to the correct length
If nOutputLen > 0 Then
    ReDim Preserve abOutput(nOutputLen - 1)
Else
    ' Catch zero-length output
    abOutput = vbNullString
End If
Debug.Print "Unpadded data=0x" & cnvHexStrFromBytes(abOutput)

```

This should result in output as follows:

```

Input data=0xFFFFFFFFFF
Required length is 8 bytes
Padded data=0xFFFFFFFFFF030303
Unpadded length is 5 bytes
Unpadded data=0xFFFFFFFFFF

```

### Example (VBA wrapper function)

```

Dim lpInput() As Byte
Dim lpBlock() As Byte
Dim lpUnpadded() As Byte
lpInput = cnvBytesFromHexStr("FDFDFDFDFD")
Debug.Print "Input data =  0x" & cnvHexStrFromBytes(lpInput)
lpBlock = padBytesBlock(lpInput, 8, 0)
Debug.Print "Padded data = 0x" & cnvHexStrFromBytes(lpBlock)
' Unpad
lpUnpadded = padUnpadBytes(lpBlock, 8, 0)
Debug.Print "Unpadded data = 0x" & cnvHexStrFromBytes(lpUnpadded)

' Special corner case - output is the empty string
lpBlock = cnvBytesFromHexStr("0808080808080808")
Debug.Print "Padded data = 0x" & cnvHexStrFromBytes(lpBlock)
lpUnpadded = padUnpadBytes(lpBlock, 8, 0)
Debug.Print "Unpadded data = 0x" & cnvHexStrFromBytes(lpUnpadded)
```

### See Also

[`PAD_UnpadBytes`](#PAD_UnpadBytes)
[`PAD_HexBlock`](#PAD_HexBlock)
[`PAD_UnpadHex`](#PAD_UnpadHex)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PAD_HexBlock"></a>PAD_HexBlock
-------------------------------------

Creates a hex-encoded input block suitably padded for encryption by a block cipher in ECB or CBC mode. 

### VBA/VB6 Syntax

`Public Declare Function PAD_HexBlock Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nMaxChars As Long, ByVal strInputHex As String, ByVal nBlockLen As Long, ByVal nOptions As Long) As Long`

`nRet = PAD_HexBlock(strOutput, nMaxChars, strInput, nBlockLen, nOptions)`

### C/C++ Syntax

`long __stdcall PAD_HexBlock(char *szOutput, long nOutChars, const char *szInput, long nBlkLen, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive the hexadecimal-encoded padded encryption block.

*nOutChars*
:   [in] specifying the maximum number of characters in *szOutput*.

*szInput*
:   [in] containing the hexadecimal-encoded data to be padded.

*nBlkLen*
:   [in] specifying the cipher block length in bytes (8 or 16).

*nOptions*
:   [in] option flags. Select one of:  

`PKI_PAD_DEFAULT` (0) to use the default PKCS5 padding  

`PKI_PAD_PKCS5` to use Pkcs5Padding (same as default)  

`PKI_PAD_1ZERO` to use OneAndZeroesPadding  

`PKI_PAD_AX923` to use the padding scheme described in ANSI X9.23  

`PKI_PAD_W3C` to use the padding scheme described in W3C <https://www.w3.org/TR/xmlenc-core1/#sec-Padding>

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`padHexBlock`](#VB_padHexBlock) (szInput As String, nBlkLen As Long, Optional nOptions As Long = 0) As String

### .NET Equivalent

Use the method associated with the relevant encryption algorithm class:

[Cipher.Pad Method](#M_Cipher_Pad_StringCipherAlgorithmPadding) (String, CipherAlgorithm, Padding)  

### Python Equivalent

static [Cipher.pad_hex](https://cryptosys.net/pki/pydocpki/class-stubs/Cipher.html#cryptosyspki.Cipher.pad_hex "External link")(datahex, alg, pad=Pad.PKCS5)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The output will be padded according to the convention specified in *nOptions*.

The output is *always* longer than the input.
Only block lengths of 8 or 16 bytes are supported.

### Example (VBA core function)

```

Dim strInputHex As String
Dim strOutputHex As String
Dim nOutChars As Long
Dim nBlockLen As Long
Dim i As Long

' Prepare test input 5 bytes long
strInputHex = "FFFFFFFFFF"
Debug.Print "Input data='" & strInputHex & "'"

' Find out the required number of characters in output
nBlockLen = 8   ' NB block length is in bytes
nOutChars = PAD_HexBlock("", 0, strInputHex, nBlockLen, 0)
Debug.Print "Required length is " & nOutChars & " characters"
' Check for error
If (nOutChars <= 0) Then Exit Function

' Pre-dimension output
strOutputHex = String(nOutChars, " ")

nOutChars = PAD_HexBlock(strOutputHex, Len(strOutputHex), strInputHex, nBlockLen, 0)
Debug.Print "Padded data='" & strOutputHex & "'"

' Now set input as padded output and remove padding
strInputHex = strOutputHex

' Remove padding...
' No need to query for length because we know the output will be shorter than input
' so make sure output is as long as the input
strOutputHex = String(Len(strInputHex), " ")
nOutChars = PAD_UnpadHex(strOutputHex, Len(strOutputHex), strInputHex, nBlockLen, 0)
Debug.Print "Unpadded length is " & nOutChars & " characters"
' Check for error
If (nOutChars <= 0) Then Exit Function

' Re-dimension the output to the correct length
strOutputHex = Left$(strOutputHex, nOutChars)
Debug.Print "Unpadded data='" & strOutputHex & "'"

```

This should result in output as follows:

```

Input data='FFFFFFFFFF'
Required length is 16 characters
Padded data='FFFFFFFFFF030303'
Unpadded length is 10 characters
Unpadded data='FFFFFFFFFF'

```

### Example (VBA wrapper function)

```

Dim strInputHex As String
Dim strOutputHex As String
strInputHex = "FDFDFD"
Debug.Print "Hex input  =" & strInputHex

strOutputHex = padHexBlock(strInputHex, 8, 0)
Debug.Print "Padded data=" & strOutputHex
Debug.Print "Unpadded   =" & padUnpadHex(strOutputHex, 8, 0)

strOutputHex = padHexBlock(strInputHex, 8, PKI_PAD_1ZERO)
Debug.Print "Padded data=" & strOutputHex
Debug.Print "Unpadded   =" & padUnpadHex(strOutputHex, 8, PKI_PAD_1ZERO)

strOutputHex = padHexBlock(strInputHex, 8, PKI_PAD_AX923)
Debug.Print "Padded data=" & strOutputHex
Debug.Print "Unpadded   =" & padUnpadHex(strOutputHex, 8, PKI_PAD_AX923)

```

### See Also

[`PAD_UnpadHex`](#PAD_UnpadHex)
[`PAD_BytesBlock`](#PAD_BytesBlock)
[`PAD_UnpadBytes`](#PAD_UnpadBytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PAD_UnpadBytes"></a>PAD_UnpadBytes
-----------------------------------------

Removes the padding from an encryption block. 

### VBA/VB6 Syntax

`Public Declare Function PAD_UnpadBytes Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutputLen As Long, ByRef lpInput As Byte, ByVal nInputLen As Long, ByVal nBlockLen As Long, ByVal nOptions As Long) As Long`

`nRet = PAD_UnpadBytes(lpOutput(0), nOutputLen, lpInput(0), nInputLen, nBlockLen, nOptions) ' Note the "(0)" after the byte array parameters`

### C/C++ Syntax

`long __stdcall PAD_UnpadBytes(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpInput, long nInputLen, long nBlkLen, long nOptions);`

### Parameters

*lpOutput*
:   [out] array to be filled with the output.

*nOutBytes*
:   [in] specifying the size of the output array in bytes.

*lpInput*
:   [in] array containing the padded data.

*nInputLen*
:   [in] specifying the length of the input in bytes.

*nBlkLen*
:   [in] specifying the cipher block length in bytes (8 or 16).

*nOptions*
:   [in] option flags. Select one of:  

`PKI_PAD_DEFAULT` (0) to use the default PKCS5 padding  

`PKI_PAD_PKCS5` to use Pkcs5Padding (same as default)  

`PKI_PAD_1ZERO` to use OneAndZeroesPadding  

`PKI_PAD_AX923` to use the padding scheme described in ANSI X9.23  

`PKI_PAD_W3C` to use the padding scheme described in W3C <https://www.w3.org/TR/xmlenc-core1/#sec-Padding>

### Returns (VBA/C)

If successful, the return value is the number of bytes in the output;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`padUnpadBytes`](#VB_padUnpadBytes) (lpInput() As Byte, nBlkLen As Long, Optional nOptions As Long = 0) As Byte()

### .NET Equivalent

Use the method associated with the relevant encryption algorithm class:

[Cipher.Unpad Method](#M_Cipher_Unpad_ByteCipherAlgorithmPadding) (Byte[], CipherAlgorithm, Padding)  

### C++ (STL) Equivalent

static bvec_t [dipki::Cipher::Unpad](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#a6c37c6b4d8a88785a393e019f2eab19d "External link") (const bvec_t &input, Alg alg, Padding pad=Padding::Pkcs5)

### Python Equivalent

static [Cipher.unpad](https://cryptosys.net/pki/pydocpki/class-stubs/Cipher.html#cryptosyspki.Cipher.unpad "External link")(data, alg, pad=Pad.PKCS5)

### Remarks

The padding is expected according to the convention specified.

If *nOutBytes* is set to zero or *lpOutput* set to 0 (or `NULL` in C or `ByVal 0&` in VBA)
then the required number of bytes will be returned. The output is *always* shorter than the input.
Only block lengths of 8 or 16 bytes are supported.

### Example (VBA core function)

This example shows how to cope with a zero-length output in VBA (you can't do `ReDim(nOutputLen - 1)` when nOutputLen is zero).

```

Dim abInput() As Byte
Dim abOutput() As Byte
Dim nOutputLen As Long
Dim nInputLen As Long
Dim nBlockLen As Long
Dim i As Long
    
nBlockLen = 8

' Prepare test input 8 bytes long, all equal to 0x08
' (the padded block for a zero-length input)
nInputLen = nBlockLen
ReDim abInput(nInputLen - 1)
For i = 0 To nInputLen - 1
    abInput(i) = CByte(nInputLen)
Next
Debug.Print "Padded data=0x(" & cnvHexStrFromBytes(abInput) & ")"
   
' Remove padding...
' No need to query for length because we know the output will be shorter than input
' so make sure output is as long as the input
nOutputLen = nInputLen
ReDim abOutput(nOutputLen - 1)
nOutputLen = PAD_UnpadBytes(abOutput(0), nOutputLen, abInput(0), nInputLen, nBlockLen, 0)
Debug.Print "Unpadded length is " & nOutputLen & " bytes"
' Check for error
If (nOutputLen < 0) Then Exit Function
' Truncate the output to the correct length
If nOutputLen > 0 Then
    ReDim Preserve abOutput(nOutputLen - 1)
Else
    ' Catch zero-length output
    abOutput = vbNullString
End If
Debug.Print "Unpadded data=0x(" & cnvHexStrFromBytes(abOutput) & ")"

```

This should result in output as follows:

```

Padded data=0x(0808080808080808)
Unpadded length is 0 bytes
Unpadded data=0x()

```

### Example (VBA wrapper function)

```

Dim lpInput() As Byte
Dim lpBlock() As Byte
Dim lpUnpadded() As Byte
lpInput = cnvBytesFromHexStr("FDFDFDFDFD")
Debug.Print "Input data =  0x" & cnvHexStrFromBytes(lpInput)
lpBlock = padBytesBlock(lpInput, 8, 0)
Debug.Print "Padded data = 0x" & cnvHexStrFromBytes(lpBlock)
' Unpad
lpUnpadded = padUnpadBytes(lpBlock, 8, 0)
Debug.Print "Unpadded data = 0x" & cnvHexStrFromBytes(lpUnpadded)

' Special corner case - output is the empty string
lpBlock = cnvBytesFromHexStr("0808080808080808")
Debug.Print "Padded data = 0x" & cnvHexStrFromBytes(lpBlock)
lpUnpadded = padUnpadBytes(lpBlock, 8, 0)
Debug.Print "Unpadded data = 0x" & cnvHexStrFromBytes(lpUnpadded)
```

### See Also

[`PAD_BytesBlock`](#PAD_BytesBlock)
[`PAD_HexBlock`](#PAD_HexBlock)
[`PAD_UnpadHex`](#PAD_UnpadHex)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PAD_UnpadHex"></a>PAD_UnpadHex
-------------------------------------

Removes the padding from a hex-encoded encryption block.

### VBA/VB6 Syntax

`Public Declare Function PAD_UnpadHex Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nMaxChars As Long, ByVal strInputHex As String, ByVal nBlockLen As Long, ByVal nOptions As Long) As Long`

`nRet = PAD_UnpadHex(strOutput, nMaxChars, strInput, nBlockLen, nOptions)`

### C/C++ Syntax

`long __stdcall PAD_UnpadHex(char *szOutput, long nOutChars, const char *szInput, long nBlkLen, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive the hexadecimal-encoded output.

*nOutChars*
:   [in] specifying the maximum number of characters in *szOutput*.

*szInput*
:   [in] containing the hexadecimal-encoded padded data.

*nBlkLen*
:   [in] specifying the cipher block length in bytes (8 or 16).

*nOptions*
:   [in] option flags. Select one of:  

`PKI_PAD_DEFAULT` (0) to use the default PKCS5 padding  

`PKI_PAD_PKCS5` to use Pkcs5Padding (same as default)  

`PKI_PAD_1ZERO` to use OneAndZeroesPadding  

`PKI_PAD_AX923` to use the padding scheme described in ANSI X9.23  

`PKI_PAD_W3C` to use the padding scheme described in W3C <https://www.w3.org/TR/xmlenc-core1/#sec-Padding>

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`padUnpadHex`](#VB_padUnpadHex) (szInput As String, nBlkLen As Long, Optional nOptions As Long = 0) As String

### .NET Equivalent

Use the method associated with the relevant encryption algorithm class:

[Cipher.Unpad Method](#M_Cipher_Unpad_StringCipherAlgorithmPadding) (String, CipherAlgorithmPadding)  

### Python Equivalent

static [Cipher.unpad_hex](https://cryptosys.net/pki/pydocpki/class-stubs/Cipher.html#cryptosyspki.Cipher.unpad_hex "External link")(datahex, alg, pad=Pad.PKCS5)

### Remarks

The padding is expected according to the convention specified in *nOptions*.

The output is *always* shorter than the input.
Only block lengths of 8 or 16 bytes are supported.
Note that it is a valid result for *szOutput* to be an empty string.

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

When using the VBA wrapper function `padUnpadHex` and there is an error, then the input is returned unchanged. The user should check for this and signal an error.
See the VBA wrapper example below. 

### Example (VBA core function)

See the example in [`PAD_HexBlock`](#PAD_HexBlock).

### Example (VBA wrapper function)

```

Dim strInputHex As String
Dim strOutputHex As String
strInputHex = "FDFDFD"
Debug.Print "Hex input  =" & strInputHex

strOutputHex = padHexBlock(strInputHex, 8, 0)
Debug.Print "Padded data=" & strOutputHex
Debug.Print "Unpadded   =" & padUnpadHex(strOutputHex, 8, 0)

strOutputHex = padHexBlock(strInputHex, 8, PKI_PAD_1ZERO)
Debug.Print "Padded data=" & strOutputHex
Debug.Print "Unpadded   =" & padUnpadHex(strOutputHex, 8, PKI_PAD_1ZERO)

strOutputHex = padHexBlock(strInputHex, 8, PKI_PAD_AX923)
Debug.Print "Padded data=" & strOutputHex
Debug.Print "Unpadded   =" & padUnpadHex(strOutputHex, 8, PKI_PAD_AX923)

```

```

Dim strInputHex As String
Dim strOutputHex As String
strInputHex = "FFFFFFFFFF030303"
Debug.Print "Hex input  =" & strInputHex
strOutputHex = padUnpadHex(strInputHex, PKI_BLK_TDEA_BYTES, 0)
Debug.Print "Unpadded   =" & strOutputHex
' Output is empty string
strInputHex = "0808080808080808"
Debug.Print "Hex input  =" & strInputHex
strOutputHex = padUnpadHex(strInputHex, PKI_BLK_TDEA_BYTES, 0)
Debug.Print "Unpadded   =" & strOutputHex
' Bad input data results in the same data being returned
strInputHex = "FFFFFFFFFFFFFFFF"
Debug.Print "Hex input  =" & strInputHex
strOutputHex = padUnpadHex(strInputHex, PKI_BLK_TDEA_BYTES, 0)
Debug.Print "Unpadded   =" & strOutputHex
If Len(strOutputHex) = Len(strInputHex) Then
    Debug.Print "DECRYPTION ERROR"
End If
Debug.Assert Len(strOutputHex) = Len(strInputHex)
```

### See Also

[`PAD_HexBlock`](#PAD_HexBlock)
[`PAD_BytesBlock`](#PAD_BytesBlock)
[`PAD_UnpadBytes`](#PAD_UnpadBytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PBE_Kdf2"></a>PBE_Kdf2
-----------------------------

Derives a key of any length from a password using the PBKDF2 algorithm from PKCS #5.

### VBA/VB6 Syntax

`Public Declare Function PBE_Kdf2 Lib "diCrPKI.dll" 
    (ByRef lpDerivedKey As Byte, ByVal nKeyLen As Long, 
    ByRef lpPwd As Byte, ByVal nPwdLen As Long, 
    ByRef lpSalt As Byte, ByVal nSaltLen As Long, 
    ByVal nCount As Long, ByVal nOptions As Long) As Long`

`nRet = PBE_Kdf2(lpDerivedKey(0), nKeyLen, lpPwd(0), nPwdLen, lpSalt(0), nSaltLen, nCount, nOptions) ' Note the "(0)" after the byte array parameters`

### C/C++ Syntax

`long __stdcall PBE_Kdf2(unsigned char *lpOutput, long nOutputLen, const unsigned char *lpPwd, long nPwdLen, const unsigned char *lpSalt, long nSaltLen, long nCount, long nOptions);`

### Parameters

*lpOutput*
:   [out] array to be filled with
derived key.

*nOutputLen*
:   [in] specifying the size of the required key
in bytes.

*lpPwd*
:   [in] array containing the password.

*nPwdLen*
:   [in] specifying the length of the password
in bytes.

*lpSalt*
:   [in] array containing the salt.

*nSaltLen*
:   [in] specifying the length of the salt
in bytes.

*nCount*
:   [in] specifying the required iteration count.

*nOptions*
:   [in] Option flags. Select one of:  

HMAC with:  

`PKI_HASH_SHA1` (0) to use the SHA-1 hash algorithm (default)  

`PKI_HASH_SHA224` to use the SHA-224 algorithm  

`PKI_HASH_SHA256` to use the SHA-256 algorithm  

`PKI_HASH_SHA384` to use the SHA-384 algorithm  

`PKI_HASH_SHA512` to use the SHA-512 algorithm  

`PKI_HASH_MD5` to use the MD5 algorithm

### Returns (VBA/C)

If successful, the return value is 0;
otherwise it returns a non-zero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`pbeKdf2`](#VB_pbeKdf2) (dkBytes As Long, lpPwd() As Byte, lpSalt() As Byte, nCount As Long, Optional nOptions As Long = 0) As Byte()

### .NET Equivalent

[Pbe.Kdf2 Method](#M_Pbe_Kdf2_Int32ByteByteInt32HashAlgorithm) (Int32, Byte[], Byte[], Int32, HashAlgorithm)  

### C++ (STL) Equivalent

static bvec_t [dipki::Pbe::Kdf2](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_pbe.html#a1ad12199140373ac7a6dbbf4a936ce65 "External link") (int dklen, const std::string password, const bvec_t &salt, int count, PrfAlg prfalg=PrfAlg::Hmac_Sha1)

### Python Equivalent

static [Pbe.kdf2](https://cryptosys.net/pki/pydocpki/class-stubs/Pbe.html#cryptosyspki.Pbe.kdf2 "External link")(dklen, password, salt, count, prfalg=0)

### Remarks

The output buffer for the derived key `abDerivedKey()` must have been dimensioned to at least the
required length.

### Example (VBA core function)

This example uses PBKDF2 as defined in PKCS #5 v2.0
from test vectors provided by Dr. Stephen Henson.
The password is "password" (without quotes).
This derived key is for the 'des-ede3-cbc' example in the test vectors
and therefore needs to be 24 bytes long.

```

    Dim abDerivedKey() As Byte
    Dim nKeyLen As Long
    Dim sPassword As String
    Dim abPwdBytes() As Byte
    Dim abSalt(7) As Byte
    Dim nCount As Long
    Dim nRet As Long
    
' Convert password String to an array of Bytes
    sPassword = "password"
    abPwdBytes = StrConv(sPassword, vbFromUnicode)
    
' Set 8-byte salt = 78 57 8E 5A 5D 63 CB 06
    abSalt(0) = &H78
    abSalt(1) = &H57
    abSalt(2) = &H8E
    abSalt(3) = &H5A
    abSalt(4) = &H5D
    abSalt(5) = &H63
    abSalt(6) = &HCB
    abSalt(7) = &H6
    
' Iteration count is 2048
    nCount = 2048
    
' Pre-dimension output for derived key to required length of 24 bytes
' (Don't forget to do this)
    nKeyLen = 24
    ReDim abDerivedKey(nKeyLen - 1)
    
' Derive PBKDF2 key using function from CryptoSys
    nRet = PBE_Kdf2(abDerivedKey(0), nKeyLen, _
      abPwdBytes(0), Len(sPassword), abSalt(0), 8&, nCount, 0&)
    
' Convert bytes to hex and print
    Debug.Print "Derived key = " & cnvHexStrFromBytes(abDerivedKey)
    Debug.Print "Correct key = BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643"

```

This should result in output as follows:

```

Derived key = BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643
Correct key = BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643

```

Had we specified the required key length to be 64 bytes instead of 24, we would 
have generated this 512-bit key:

```

BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643C4B150DEF7751122
4479994567F2E9B4E3BD0DF7AEDA3022B1F26051D81505C794F8940C04DF1144

```

This second example shows how other SHA-2 hash functions can be used.

```

    Dim abDerivedKey() As Byte
    Dim nKeyLen As Long
    Dim sPassword As String
    Dim abPwdBytes() As Byte
    Dim abSalt(7) As Byte
    Dim nSaltBytes As Long
    Dim nCount As Long
    Dim nRet As Long
    
' Convert password String to an array of Bytes
    sPassword = "password"
    abPwdBytes = StrConv(sPassword, vbFromUnicode)
    
' Set 8-byte salt = 78 57 8E 5A 5D 63 CB 06
    abSalt(0) = &H78
    abSalt(1) = &H57
    abSalt(2) = &H8E
    abSalt(3) = &H5A
    abSalt(4) = &H5D
    abSalt(5) = &H63
    abSalt(6) = &HCB
    abSalt(7) = &H6
    nSaltBytes = 8
    
' Iteration count is 2048
    nCount = 2048
    
' Pre-dimension output for derived key to required length of 24 bytes
' (Don't forget to do this)
    nKeyLen = 24
    ReDim abDerivedKey(nKeyLen - 1)
    
' Derive PBKDF2 key using function from CryptoSys API with default HMAC-SHA-1
    nRet = PBE_Kdf2(abDerivedKey(0), nKeyLen, _
      abPwdBytes(0), Len(sPassword), abSalt(0), nSaltBytes, nCount, PKI_HASH_SHA1)
' Convert bytes to hex and print
    Debug.Print "Derived key {HMAC-SHA-1}   = " & cnvHexStrFromBytes(abDerivedKey)
    
' Derive PBKDF2 key using function from CryptoSys API with HMAC-SHA-256
    nRet = PBE_Kdf2(abDerivedKey(0), nKeyLen, _
      abPwdBytes(0), Len(sPassword), abSalt(0), nSaltBytes, nCount, PKI_HASH_SHA256)
    Debug.Print "Derived key {HMAC-SHA-256} = " & cnvHexStrFromBytes(abDerivedKey)

' Derive PBKDF2 key using function from CryptoSys API with HMAC-SHA-224
    nRet = PBE_Kdf2(abDerivedKey(0), nKeyLen, _
      abPwdBytes(0), Len(sPassword), abSalt(0), nSaltBytes, nCount, PKI_HASH_SHA224)
    Debug.Print "Derived key {HMAC-SHA-224} = " & cnvHexStrFromBytes(abDerivedKey)

```

This should result in output as follows:

```

Derived key {HMAC-SHA-1}   = BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643
Derived key {HMAC-SHA-256} = 97B5A91D35AF542324881315C4F849E327C4707D1BC9D322
Derived key {HMAC-SHA-224} = 10CFFEDFB13503519969151E466F587028E0720B387F9AEF

```

### Example (VBA wrapper function)

```

Dim lpDK() As Byte
Dim strPassword As String
Dim lpSalt() As Byte
Dim nCount As Long
strPassword = "password"
lpSalt = cnvBytesFromHexStr("78 57 8E 5A 5D 63 CB 06")
nCount = 2048
lpDK = pbeKdf2(24, StrConv(strPassword, vbFromUnicode), lpSalt, nCount)
Debug.Print "Derived key = " & cnvHexStrFromBytes(lpDK)
Debug.Print "Correct key = BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643"

lpDK = pbeKdf2(24, StrConv(strPassword, vbFromUnicode), lpSalt, nCount, PKI_HASH_SHA256)
Debug.Print "Derived key {HMAC-SHA-256} = " & cnvHexStrFromBytes(lpDK)
Debug.Print "Correct key {HMAC-SHA-256} = 97B5A91D35AF542324881315C4F849E327C4707D1BC9D322"

```

### See Also

[`PBE_Kdf2Hex`](#PBE_Kdf2Hex)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PBE_Kdf2Hex"></a>PBE_Kdf2Hex
-----------------------------------

Derives a key of any length from a password using the PBKDF2 algorithm
from PKCS #5 with the salt and output derived key encoded in hexadecimal.

### VBA/VB6 Syntax

`Public Declare Function PBE_Kdf2Hex Lib "diCrPKI.dll" 
    (ByVal strOutput As String, ByVal nMaxChars As Long, ByVal nKeyBytes As Long,
    ByVal strPwd As String, ByVal strSaltHex As String, 
    ByVal nCount As Long, ByVal nOptions As Long) As Long`

`nRet = PBE_Kdf2Hex(strDerivedKey, nMaxChars, nKeyLen, strPassword, strSaltHex, nCount, nOptions)`

### C/C++ Syntax

`long __stdcall PBE_Kdf2Hex(char *szOutput, long nMaxChars, long dkBytes, const char *szPwd, const char *szSaltHex, long nCount, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive the hexadecimal-encoded derived key.

*nMaxChars*
:   [in] specifying the maximum number of characters in *szOutput*.

*dkBytes*
:   [in] specifying the size of the required key in bytes.

*szPwd*
:   [in] containing the password.

*szSaltHex*
:   [in] containing the salt in hex format.

*nCount*
:   [in] specifying the required iteration count.

*nOptions*
:   [in] Option flags. Select one of:  

HMAC with:  

`PKI_HASH_SHA1` (0) to use the SHA-1 hash algorithm (default)  

`PKI_HASH_SHA224` to use the SHA-224 algorithm  

`PKI_HASH_SHA256` to use the SHA-256 algorithm  

`PKI_HASH_SHA384` to use the SHA-384 algorithm  

`PKI_HASH_SHA512` to use the SHA-512 algorithm  

`PKI_HASH_MD5` to use the MD5 algorithm

### Returns (VBA/C)

If successful, the return value is 0;
otherwise it returns a non-zero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`pbeKdf2Hex`](#VB_pbeKdf2Hex) (dkBytes As Long, szPwd As String, szSaltHex As String, nCount As Long, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Pbe.Kdf2 Method](#M_Pbe_Kdf2_Int32StringStringInt32HashAlgorithm) (Int32, String, String, Int32, HashAlgorithm)  

### Remarks

The output string *szOutput* should be pre-dimensioned to be at least **double** the 
required key length in bytes. (Hint: specify *nMaxChars* as `Len(strOutput)`).
ANSI C users [must add one to this value](#cusersaddone) when allocating memory.
The seed *szSaltHex* is specified in hex format and can be any even number of hex digits in length.
The password *szPassword* is normal text, not hexadecimal.

### Example (VBA core function)

```

Dim strDerivedKey As String
Dim nKeyLen As Long
Dim strPassword As String
Dim strSaltHex As String
Dim nCount As Long
Dim nRet As Long

strPassword = "password"  ' NB normal text, not hex

' Set 8-byte salt = 78 57 8E 5A 5D 63 CB 06
strSaltHex = "78578E5A5D63CB06"

' Iteration count is 2048
nCount = 2048

' Pre-dimension output string for derived key to 
' required length of 24 bytes i.e. 48 hex chars
' (Don't forget to do this)
nKeyLen = 24
strDerivedKey = String(2 * nKeyLen, " ")

' Derive PBKDF2 key using function from CryptoSys API
nRet = PBE_Kdf2Hex(strDerivedKey, Len(strDerivedKey), nKeyLen, _
	strPassword, strSaltHex, nCount, 0)

' Check against test vector
Debug.Print "Derived key = " & strDerivedKey
Debug.Print "Correct key = BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643"

```

This should result in output as follows:

```

Derived key = BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643
Correct key = BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643

```

### Example (VBA wrapper function)

```

Dim strDK As String
Dim strPassword As String
Dim strSaltHex As String
Dim nCount As Long
strPassword = "password"
strSaltHex = "78578E5A5D63CB06"
nCount = 2048
strDK = pbeKdf2Hex(24, strPassword, strSaltHex, nCount)
Debug.Print "Derived key = " & strDK
Debug.Print "Correct key = BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643"
```

### See Also

[`PBE_Kdf2`](#PBE_Kdf2)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PBE_Scrypt"></a>PBE_Scrypt
---------------------------------

Derives a key of any length from a password using the SCRYPT algorithm.

### VBA/VB6 Syntax

`Public Declare Function PBE_Scrypt Lib "diCrPKI.dll" (ByRef lpDerivedKey As Byte, ByVal nKeyLen As Long, ByRef lpPwd As Byte, ByVal nPwdLen As Long, ByRef lpSalt As Byte, ByVal nSaltLen As Long, ByVal nParamN As Long, ByVal nParamR As Long, ByVal nParamP As Long, ByVal nOptions As Long) As Long`

`nRet = PBE_Scrypt(abDerivedKey(0), nKeyLen, abPwd(0), nPwdLen, abSalt(0), nSaltLen, nParamN, nParamR, nParamP, nOptions)
' Note the "(0)" after the byte array parameters`

### C/C++ Syntax

`long __stdcall PBE_Scrypt(unsigned char *lpDerivedKey, long nKeyLen, const unsigned char *lpPwd, long nPwdLen, const unsigned char *lpSalt, long nSaltLen, long nParamN, long nParamR, long nParamP, long nOptions);`

### Parameters

*lpDerivedKey*
:   [out] Byte array to be filled with derived key.

*nKeyLen*
:   [in] size of required key in bytes.

*lpPwd*
:   [in] Byte array containing the password.

*nPwdLen*
:   [in] length of the password in bytes.

*lpSalt*
:   [in] Byte array containing the salt.

*nSaltLen*
:   [in] length of the salt in bytes.

*nParamN*
:   [in] CPU/Memory cost parameter *N* (`"costParameter"`) a number greater than one and a power of 2.

*nParamR*
:   [in] Block size *r* (`"blockSize"`)

*nParamP*
:   [in] Parallelization parameter *p* (`"parallelizationParameter"`)

*nOptions*
:   [in] Option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is 0;
otherwise it returns a non-zero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`pbeScrypt`](#VB_pbeScrypt) (dkBytes As Long, lpPwd() As Byte, lpSalt() As Byte, nParamN As Long, nParamR As Long, nParamP As Long, Optional nOptions As Long = 0) As Byte()

### .NET Equivalent

[Pbe.Scrypt Method](#M_Pbe_Scrypt_Int32ByteByteInt32Int32Int32) (Int32, Byte[], Byte[], Int32, Int32, Int32) 

### C++ (STL) Equivalent

static bvec_t [dipki::Pbe::Scrypt](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_pbe.html#a802fc639667ab1999be8e1c19cf16cd1 "External link") (int dklen, const std::string password, const bvec_t &salt, int N, int r, int p)

### Python Equivalent

static [Pbe.scrypt](https://cryptosys.net/pki/pydocpki/class-stubs/Pbe.html#cryptosyspki.Pbe.scrypt "External link")(dklen, pwdbytes, salt, N, r, p)

### Remarks

This uses the SCRYPT algorithm from [[RFC7914](#RFC7914)].
There are restrictions on the values of the parameters *N*, *r* and *p*.
In particular, *N* must be larger than 1 and a power of 2.

The output buffer for the derived key *abDerivedKey* must have been dimensioned to at least the
required length *nKeyLen* in bytes.

### Example (VBA core function)

Two examples from [[RFC7914](#RFC7914)].

```

Dim abPwd() As Byte
Dim abSalt() As Byte
Dim abDK() As Byte
Dim nKeyLen As Long
Dim nPwdlen As Long
Dim nSaltLen As Long
Dim nRet As Long

nKeyLen = 64
' Dimension key byte array
ReDim abDK(nKeyLen - 1)
' Convert strings to byte array form
abPwd = StrConv("password", vbFromUnicode)
abSalt = StrConv("NaCl", vbFromUnicode)
' Get lengths in bytes
nPwdlen = UBound(abPwd) + 1
nSaltLen = UBound(abSalt) + 1
' Call the SCRYPT function to derive a 64-byte key with parameters N=1024, r=8, p=16
nRet = PBE_Scrypt(abDK(0), nKeyLen, abPwd(0), nPwdlen, abSalt(0), nSaltLen, 1024, 8, 16, 0)
Debug.Print "PBE_Scrypt() returns " & nRet & " (expecting 0)"
Debug.Print "KEY=" & cnvHexStrFromBytes(abDK)	

```

```

PBE_Scrypt() returns 0 (expecting 0)
KEY=FDBABE1C9D3472007856E7190D01E9FE7C6AD7CBC8237830E77376634B373162
2EAF30D92E22A3886FF109279D9830DAC727AFB94A83EE6D8360CBDFA2CC0640

```

In this second example, we need to pass zero-length byte arrays (representing the empty string) for the password and salt.

```

' INPUT: (N=16, r=1, p=1)
' P="", S="" => empty strings => byte arrays of length zero
' VBA ISSUE: we cannot pass an empty byte array in the usual way `abPwd(0)`
' because it gives a "Subscript out of range" error.
' FIX: pass `0` for the array parameters and zero for the lengths
nRet = PBE_Scrypt(abDK(0), nKeyLen, 0, 0, 0, 0, 16, 1, 1, 0)
Debug.Print "PBE_Scrypt() returns " & nRet & " (expecting 0)"
Debug.Print "KEY=" & cnvHexStrFromBytes(abDK)

```

```

PBE_Scrypt() returns 0 (expecting 0)
KEY=77D6576238657B203B19CA42C18A0497F16B4844E3074AE8DFDFFA3FEDE21442
FCD0069DED0948F8326A753A0FC81F17E8D3E0FB2E0D3628CF35E20C38D18906

```

### Example (VBA wrapper function)

```

Dim lpPwd() As Byte
Dim lpSalt() As Byte
Dim lpDK() As Byte
lpPwd = StrConv("password", vbFromUnicode)
lpSalt = StrConv("NaCl", vbFromUnicode)
lpDK = pbeScrypt(64, lpPwd, lpSalt, 1024, 8, 16, 0)
Debug.Print "DK=" & cnvHexStrFromBytes(lpDK)
Debug.Print "OK=FDBABE1C9D3472007856E7190D01E9FE7C6AD7CBC8237830E77376634B3731622EAF30D92E22A3886FF109279D9830DAC727AFB94A83EE6D8360CBDFA2CC0640"
' INPUT: (N=16, r=1, p=1)
' P="", S="" => empty strings => byte arrays of length zero
' IMPORTANT: dummy variables *must* be independent
Dim lpDummy1() As Byte
Dim lpDummy2() As Byte
lpDK = pbeScrypt(64, lpDummy1, lpDummy2, 16, 1, 1, 0)
Debug.Print "DK=" & cnvHexStrFromBytes(lpDK)
Debug.Print "OK=77D6576238657B203B19CA42C18A0497F16B4844E3074AE8DFDFFA3FEDE21442FCD0069DED0948F8326A753A0FC81F17E8D3E0FB2E0D3628CF35E20C38D18906"

```

```

Dim strDerivedKey As String
strDerivedKey = pbeScryptHex(64, "pleaseletmein", cnvHexStrFromString("SodiumChloride"), 16384, 8, 1, 0)
Debug.Print "Derived key = " & strDerivedKey
Debug.Print "OK =          " & "7023BDCB3AFD7348461C06CD81FD38EBFDA8FBBA904F8E3EA9B543F6545DA1F2D5432955613F0FCF62D49705242A9AF9E61E85DC0D651E40DFCF017B45575887"

```

### See Also

[`PBE_ScryptHex`](#PBE_ScryptHex)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PBE_ScryptHex"></a>PBE_ScryptHex
---------------------------------------

Derives a key of any length from a password using the SCRYPT algorithm
with the salt and derived key encoded in hexadecimal.

### VBA/VB6 Syntax

`Public Declare Function PBE_ScryptHex Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nMaxChars As Long, ByVal dkBytes As Long, ByVal strPwd As String, ByVal strSaltHex As String, ByVal nParamN As Long, ByVal nParamR As Long, ByVal nParamP As Long, ByVal nOptions As Long) As Long`

`nRet = PBE_ScryptHex(strDerivedKey, nMaxChars, dkBytes, strPassword, strSaltHex, nParamN, nParamR, nParamP, nOptions)`

### C/C++ Syntax

`long __stdcall PBE_ScryptHex(char *szOutput, long nMaxChars, long dkBytes, const char *szPwd, const char *szSaltHex, long nParamN, long nParamR, long nParamP, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive the hexadecimal-encoded derived key.

*nMaxChars*
:   [in] specifying the maximum number of characters in *szOutput*.

*dkBytes*
:   [in] specifying the size of the required key in bytes.

*szPwd*
:   [in] containing the password (as normal text).

*szSaltHex*
:   [in] containing the salt in hex format.

*nParamN*
:   [in] CPU/Memory cost parameter *N* (`"costParameter"`) a number greater than one and a power of 2.

*nParamR*
:   [in] Block size *r* (`"blockSize"`)

*nParamP*
:   [in] Parallelization parameter *p* (`"parallelizationParameter"`)

*nOptions*
:   [in] Option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is 0;
otherwise it returns a non-zero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`pbeScryptHex`](#VB_pbeScryptHex) (dkBytes As Long, szPwd As String, szSaltHex As String, nParamN As Long, nParamR As Long, nParamP As Long, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Pbe.Scrypt Method](#M_Pbe_Scrypt_Int32StringStringInt32Int32Int32) (Int32, String, String, Int32, Int32, Int32)  

### Remarks

The output string *szOutput* should be pre-dimensioned to be at least **double** the 
required key length in bytes. (Hint: specify *nMaxChars* as `Len(strOutput)`).
The seed *szSaltHex* is specified in hex format and can be any even number of hex digits in length.
The password *szPassword* is normal text, not hexadecimal.

### Example (VBA core function)

```

Dim strDerivedKey As String
Dim nKeyLen As Long
Dim strPassword As String
Dim strSaltHex As String
Dim nRet As Long

strPassword = "pleaseletmein"  ' NB normal text, not hex
strSaltHex = cnvHexStrFromString("SodiumChloride")

' Pre-dimension output string for derived key to
' required length of two times number of bytes
' (Don't forget to do this)
nKeyLen = 64
strDerivedKey = String(2 * nKeyLen, " ")

' Derive key using SCRYPT
nRet = PBE_ScryptHex(strDerivedKey, Len(strDerivedKey), nKeyLen, _
    strPassword, strSaltHex, 16384, 8, 1, 0)

Debug.Print "Derived key = " & strDerivedKey

```

This should result in output as follows:

```

Derived key = 7023BDCB3AFD7348461C06CD81FD38EBFDA8FBBA904F8E3EA9B543F6545DA1F2
D5432955613F0FCF62D49705242A9AF9E61E85DC0D651E40DFCF017B45575887

```

### Example (VBA wrapper function)

```

Dim strDerivedKey As String
strDerivedKey = pbeScryptHex(64, "pleaseletmein", cnvHexStrFromString("SodiumChloride"), 16384, 8, 1, 0)
Debug.Print "Derived key = " & strDerivedKey
Debug.Print "OK =          " & "7023BDCB3AFD7348461C06CD81FD38EBFDA8FBBA904F8E3EA9B543F6545DA1F2D5432955613F0FCF62D49705242A9AF9E61E85DC0D651E40DFCF017B45575887"
```

### See Also

[`PBE_Scrypt`](#PBE_Scrypt)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PEM_FileFromBinFile"></a>PEM_FileFromBinFile
---------------------------------------------------

Creates a PEM file from a binary file .

### VBA/VB6 Syntax

`Public Declare Function PEM_FileFromBinFile Lib "diCrPKI.dll" 
    (ByVal strOutputFile As String, ByVal strFileIn As String, 
    ByVal strHeader As String, ByVal nLineLen As Long) As Long`

`nRet = PEM_FileFromBinFile(strOutputFile, strFileIn, strHeader, nLineLen)`

### C/C++ Syntax

`long __stdcall PEM_FileFromBinFile(const char *szFileOut, const char *szFileIn, const char *szHeader, long nLineLen);`

### Parameters

*szFileOut*
:   [in] with name of output file to be created.

*szFileIn*
:   [in] with the filename of the binary file to be converted.

*szHeader*
:   [in] specifying the header to be used. Leave empty to omit the PEM header and footer.

*nLineLen*
:   [in] the maximum length of a line in the resulting PEM file (default = 64 characters).

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

[Pem.FileFromBinFile Method](#M_Pem_FileFromBinFile) Pem.FileFromBinFile Method 

### C++ (STL) Equivalent

static int [dipki::Pem::FileFromBinFile](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_pem.html#a94dbda8a7c4e2bf2292329e83fe245dc "External link") (const std::string &fileToMake, const std::string &fileIn, const std::string &header="", int lineLen=0, Eol eol=Eol::Windows)

### Remarks

This function takes the contents of *any* file (usually an ASN.1 DER- or BER-encoded binary file), 
treats it as binary data, encodes in base64 format, and encapsulates in a PEM-style 
header and footer.
Leave the header blank to omit the PEM encapsulation and just output plain base64.
The default for *nLineLen* is 64 characters. The recommended limit is 72 characters.

A PEM file is a text file containing encapsulated base64 data of the form

```

-----BEGIN FOO BAR-----
MIAGCSqGSIb3DQEHA...
-----END FOO BAR-----

```

The label in the header between `"BEGIN "` and the following five dash characters `"-----"` is set 
using the *szHeader* parameter.
In the above example, `strHeader="FOO BAR"`. You are free to use whatever word or words you like.
In this Toolkit, we make no checks that the content of the file matches the header. However, other applications may.

Here is a list of commonly-used headers for PKI-related files.

| PEM Header | Type of file | Typical file extensions | Comment |
| --- | --- | --- | --- |
| `CERTIFICATE` | X.509 certificate | `.cer,.der,.pem,.crt` | Should contain exactly one certificate |
| `CERTIFICATE REQUEST` | PKCS#10 certificate signing request | `.csr,.p10` |  |
| `X509 CRL` | X.509 certificate revocation list | `.crl` |  |
| `PKCS12` | PFX file to PKCS#12 | `.p12,.pfx` |  |
| `ENCRYPTED PRIVATE KEY` | PKCS#8 key | `.p8e,.key,(.epk)` | Our default private key format |
| `RSA PUBLIC KEY` | PKCS#1 public key | `.p1,.pub` | Our default public key format |
| `PUBLIC KEY` | SubjectPublicKeyInfo |  | OpenSSL format (`PKI_KEY_FORMAT_SSL`) |
| `PRIVATE KEY` | Unencrypted PKCS#8 private key info | `.p8,.pri,.key` | Our private key info format |
| `RSA PRIVATE KEY` | Unencrypted PKCS#1 private key |  | OpenSSL format (`PKI_KEY_FORMAT_SSL`) |
| `PKCS7` | CMS object to PKCS#7 | `.p7m,.p7s,.p7c,.p7b,.p7z` | Used by OpenSSL |
| `PKCS #7 SIGNED DATA` | ditto |  | Used by Thawte for Microsoft users |
| `NETSCAPE CERTIFICATE CHAIN` | "certs-only" PKCS#7 | `.p7c,.p7b` | Used by Thawte for Netscape users |

**Update April 2015:** see RFC 7468 "Textual Encodings of PKIX, PKCS, and CMS Structures" [[RFC7468](#RFC7468)] 
for more definitive rules and recommendations on this subject.

### Example

```

Dim nRet As Long
Dim strBinFile As String
Dim strPemFile As String
Dim strDigest As String

' Input file is a DER-encoded X.509 certificate
' (at 227 bytes, the smallest we could devise)
strBinFile = "smallca.cer"
strPemFile = "smallca.pem.cer"

' Convert to a PEM file
nRet = PEM_FileFromBinFile(strPemFile, strBinFile, "CERTIFICATE", 72)
Debug.Print "PEM_FileFromBinFile returns " & nRet & " (expecting 0)"

' To prove we did it properly, compute the thumbprint of the two certs
strDigest = String(PKI_SHA1_CHARS, " ")
nRet = X509_CertThumb(strBinFile, strDigest, Len(strDigest), PKI_HASH_SHA1)
If nRet > 0 Then
    Debug.Print "SHA-1(der-file)=" & strDigest
Else
    Debug.Print "ERROR: computing cert thumb"
End If
nRet = X509_CertThumb(strPemFile, strDigest, Len(strDigest), PKI_HASH_SHA1)
If nRet > 0 Then
    Debug.Print "SHA-1(pem-file)=" & strDigest
Else
    Debug.Print "ERROR: computing cert thumb"
End If

```

The output should be 

```

PEM_FileFromBinFile returns 0 (expecting 0)
SHA-1(der-file)=a36b1bfa0af41a2785066b2d5135b67011ac3b7f
SHA-1(pem-file)=a36b1bfa0af41a2785066b2d5135b67011ac3b7f

```

The X.509 file in this example is

```

-----BEGIN CERTIFICATE-----
MIHgMIGaAgEBMA0GCSqGSIb3DQEBBQUAMAwxCjAIBgNVBAMTAUEwHhcNMDcwODAyMDIwMDAx
WhcNMTEwODAyMDIwMDAxWjAMMQowCAYDVQQDEwFBMEowDQYJKoZIhvcNAQEBBQADOQAwNgIx
A1KSJlPSmQAqQgDHUISaUsCrHbIZe249i6jFtfN3rA7czrP4CXS3mjvMFf0AsxV6BwIBAzAN
BgkqhkiG9w0BAQUFAAMyAACeT7GtgmBRKUN20cIyNEGneEvmNxaliuBEVkg2npbyEBgeHXOH
6jqj9Ase348UN/Q=
-----END CERTIFICATE-----

```

The binary file is

```

000000  30 81 e0 30 81 9a 02 01 01 30 0d 06 09 2a 86 48  0..0.....0...*.H
000010  86 f7 0d 01 01 05 05 00 30 0c 31 0a 30 08 06 03  ........0.1.0...
000020  55 04 03 13 01 41 30 1e 17 0d 30 37 30 38 30 32  U....A0...070802
000030  30 32 30 30 30 31 5a 17 0d 31 31 30 38 30 32 30  020001Z..1108020
000040  32 30 30 30 31 5a 30 0c 31 0a 30 08 06 03 55 04  20001Z0.1.0...U.
000050  03 13 01 41 30 4a 30 0d 06 09 2a 86 48 86 f7 0d  ...A0J0...*.H...
000060  01 01 01 05 00 03 39 00 30 36 02 31 03 52 92 26  ......9.06.1.R.&
000070  53 d2 99 00 2a 42 00 c7 50 84 9a 52 c0 ab 1d b2  S...*B..P..R....
000080  19 7b 6e 3d 8b a8 c5 b5 f3 77 ac 0e dc ce b3 f8  .{n=.....w......
000090  09 74 b7 9a 3b cc 15 fd 00 b3 15 7a 07 02 01 03  .t..;......z....
0000a0  30 0d 06 09 2a 86 48 86 f7 0d 01 01 05 05 00 03  0...*.H.........
0000b0  32 00 00 9e 4f b1 ad 82 60 51 29 43 76 d1 c2 32  2...O...`Q)Cv..2
0000c0  34 41 a7 78 4b e6 37 16 a5 8a e0 44 56 48 36 9e  4A.xK.7....DVH6.
0000d0  96 f2 10 18 1e 1d 73 87 ea 3a a3 f4 0b 1e df 8f  ......s..:......
0000e0  14 37 f4                                         .7.

```

```

>certmgr smallca.cer
==============Certificate # 1 ==========
Subject::
  [0,0] 2.5.4.3 (CN) A
Issuer::
  [0,0] 2.5.4.3 (CN) A
SerialNumber::
   01
SHA1 Thumbprint::
      A36B1BFA 0AF41A27 85066B2D 5135B670 11AC3B7F
MD5 Thumbprint::
      575A5AEE 32B3810F EFA71CEC 5EAD35DD
Key MD5 Thumbprint::
      42B4A712 FB3B4C12 B75CB679 1D0C0E01
NotBefore::
  Thu Aug 02 10:00:01 2007
NotAfter::
  Tue Aug 02 10:00:01 2011
==============No CTLs ==========
==============No CRLs ==========
==============================================
CertMgr Succeeded

```

### See Also

[PEM_FileFromBinFileEx](#PEM_FileFromBinFileEx)
[PEM_FileToBinFile](#PEM_FileToBinFile)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PEM_FileFromBinFileEx"></a>PEM_FileFromBinFileEx
-------------------------------------------------------

Creates a PEM file from a binary file with extended options.

### VBA/VB6 Syntax

`Public Declare Function PEM_FileFromBinFileEx Lib "diCrPKI.dll" 
(ByVal strOutputFile As String, ByVal strFileIn As String, ByVal strHeader As String, ByVal nLineLen As Long, ByVal nOptions As Long) As Long`

`nRet = PEM_FileFromBinFileEx(strOutputFile, strFileIn, strHeader, nLineLen, nOptions)`

### C/C++ Syntax

`long __stdcall PEM_FileFromBinFileEx(const char *szFileOut, const char *szFileIn, const char *szHeader, long nLineLen, long nOptions);`

### Parameters

*szFileOut*
:   [in] with name of output file to be created.

*szFileIn*
:   [in] with the filename of the binary file to be converted.

*szHeader*
:   [in] specifying the header to be used. Leave empty to omit the PEM header and footer.

*nLineLen*
:   [in] the maximum length of a line in the resulting PEM file (default = 64 characters).

*nOptions*
:   [in] option flags:  

`PKI_DEFAULT` (0) for default options  

`PKI_KEY_FORMAT_SSL` to create the output file with Unix/SSL line endings (default = Windows CR-LF line endings)

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

[Pem.FileFromBinFile Method](#M_Pem_FileFromBinFile) Pem.FileFromBinFile Method  

### Python Equivalent

static [Pem.from_binfile](https://cryptosys.net/pki/pydocpki/class-stubs/Pem.html#cryptosyspki.Pem.from_binfile "External link")(outputfile, filein, header, linelen=64, eol=EOL.DEFAULT)

### Remarks

See the remarks for [PEM_FileFromBinFile()](#PEM_FileFromBinFile).
This extension was added to create PEM format files compatible with those created by Open SSL, which uses Unix line endings 
(a single LF character as opposed to the CR-LF pair used in Windows files).

### Example

### See Also

[PEM_FileFromBinFile](#PEM_FileFromBinFile)
[PEM_FileToBinFile](#PEM_FileToBinFile)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PEM_FileToBinFile"></a>PEM_FileToBinFile
-----------------------------------------------

Converts the contents of a PEM file into a binary file.

### VBA/VB6 Syntax

`Public Declare Function PEM_FileToBinFile Lib "diCrPKI.dll" 
    (ByVal strOutputFile As String, ByVal strFileIn As String) As Long`

`nRet = PEM_FileToBinFile(strOutputFile, strFileIn)`

### C/C++ Syntax

`long __stdcall PEM_FileToBinFile(const char *szFileOut, const char *szFileIn);`

### Parameters

*szFileOut*
:   [in] with name of output file to be created.

*szFileIn*
:   [in] with the filename of the PEM-encoded  file to be converted.

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

[Pem.FileToBinFile Method](#M_Pem_FileToBinFile)  

### C++ (STL) Equivalent

static int [dipki::Pem::FileToBinFile](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_pem.html#a5c1beb5fe93e5e1ede340216f283f04d "External link") (const std::string &fileToMake, const std::string &fileIn)

### Python Equivalent

static [Pem.to_binfile](https://cryptosys.net/pki/pydocpki/class-stubs/Pem.html#cryptosyspki.Pem.to_binfile "External link")(outputfile, filein)

### Remarks

Any base64-encoded data found between a PEM header and footer is converted into binary data and saved as a file.

```

-----BEGIN FOO BAR-----
MIAGCSqGSIb3DQEHA...
-----END FOO BAR-----

```

### Example

```

Dim nRet As Long
Dim strBinFile As String
Dim strPemFile As String
Dim strDigest As String

' Input file is a PEM-encoded X.509 certificate
strPemFile = "smallca.pem.cer"
strBinFile = "smallca-copy.cer"

' Convert to a binary file
nRet = PEM_FileToBinFile(strBinFile, strPemFile)
Debug.Print "PEM_FiletoBinFile returns " & nRet & " (expecting 0)"

```

### See Also

[PEM_FileFromBinFile](#PEM_FileFromBinFile)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PFX_MakeFile"></a>PFX_MakeFile
-------------------------------------

Creates a simple PFX (PKCS-12) file from an
X.509 certificate and (optional) encrypted private key file.

### VBA/VB6 Syntax

`Public Declare Function PFX_MakeFile Lib "diCrPKI.dll" 
    (ByVal strOutputFile As String, ByVal strCertList As String, 
    ByVal strKeyFile As String, ByVal strPassword As String, 
    ByVal strFriendlyName As String, ByVal nOptions As Long) As Long`

`nRet = PFX_MakeFile(strOutputFile, strCertList, strKeyFile, strPassword, strFriendlyName, nOptions)`

### C/C++ Syntax

`long __stdcall PFX_MakeFile(const char *szFileOut, const char *szCertList, const char *szEpkFile, const char *szPassword, const char *szFriendlyName, long nOptions);`

### Parameters

*szFileOut*
:   [in] name of output file to be created.

*szCertList*
:   [in] (required) filename of the subject's X.509 certificate
		(or a string containing the certificate in [base64 representation](#base64forcert))
		followed by optional extra certificates to be included separated by a semicolon (`;`).

*szEpkFile*
:   [in] filename of the subject's pkcs-8 encrypted private key
	 (or a string containing the key in [PEM format](#pemstring)).
	 Pass an empty string `""` to exclude the private key.

*szPassword*
:   [in] password for the encrypted private key.

*szFriendlyName*
:   [in] friendly name identification for the subject (optional).

*nOptions*
:   [in] option flags:  

`PKI_DEFAULT` (0) for default options: re-encrypt private key with "TripleDES-SHA1", encrypt certificate with 40-bit RC2, output in DER binary form.  

`PKI_PFX_CLONE_KEY` to store the private key in the exact form of the pkcs-8 input file (default is to re-encrypt with 3DES)  

Add one of the following:  

`PKI_PFX_PLAIN_CERT` to store the certificate in unencrypted form (default is encrypted)  

`PKI_PFX_STRONG_CERT` to encrypt the certificate with "stronger" TripleDES-SHA1 (default is "weak" 40-bit RC2)  

Or, *new in [v20.5]*, to override the above encryption options, use instead 

`PKI_PFX_AES256_SHA256` to encrypt both the private key and certificate using "AES256-SHA256"  

Then add any of these options:  

`PKI_KEY_FORMAT_PEM` to create the output file in PEM format (default is DER-encoded binary)  

`PKI_PFX_ALT_FORMAT` to create a PFX file with the exact peculiarities used by Microsoft (default is OpenSSL format)

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`pfxMakeFile`](#VB_pfxMakeFile) (szFileOut As String, szCertList As String, Optional szKeyFile As String = "", Optional szPassword As String = "", Optional szFriendlyName As String = "", Optional nOptions As Long = 0) As Long

### .NET Equivalent

[Pfx.MakeFile Method](#M_Pfx_MakeFile)  

### C++ (STL) Equivalent

static int [dipki::Pfx::MakeFile](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_pfx.html#a7a42e6bb9df32c43243b0d6910bded9b "External link") (const std::string &fileToMake, const std::string &certList, const std::string &privateKeyFile="", const std::string &password="", const std::string &friendlyName="", Opts opts=Opts::Default)

### Python Equivalent

static [Pfx.make_file](https://cryptosys.net/pki/pydocpki/class-stubs/Pfx.html#cryptosyspki.Pfx.make_file "External link")(outputfile, certlist, prikeyfile="", password="", friendlyname="", opts=0)

### Remarks

At least one certificate must be specified in the *szCertList* argument. Add additional certificate names (or base64 representations)
separated by a semicolon (`;`). 
The first certificate in the list *must* be the matching certificate for the private key, if included. 
The default behaviour is to save the certificate(s) encrypted using the "standard" weak 40-bit
RC2 encryption (`pbeWithSHAAnd40BitRC2-CBC`) as used (until recently) by Windows Certificate Manager and OpenSSL,
and the private key is re-encrypted using the "standard" TripleDES-SHA1 algorithm (`pbeWithSHAAnd3-KeyTripleDES-CBC`). 

*[New in v12.3]*
Use the `PKI_PFX_STRONG_CERT` option to encrypt the certificate with "stronger" Triple DES, the same as the default key encryption algorithm.
The `PKI_PFX_PLAIN_CERT` option takes precedence.

*[New in v20.5]*
Use the `PKI_PFX_AES256_SHA256` option to encrypt both the private key and certificate using "AES256-SHA256".

The *szFriendlyName* parameter is optional.
To exclude the private key just pass an empty *szKeyFile* parameter.

To help users of a certain brain-dead web service in Mexico which cannot cope with anything else, 
the default file format is the *exact* format that would be created by OpenSSL. 
If you really need Microsoft's peculiarities†, then
add the `PKI_PFX_ALT_FORMAT` option flag.

Any form of PKCS-12 file created by this function should be importable into 
Windows Certificate Manager/Outlook (use a .pfx extension for the output file) and Mozilla/Firefox (use a .p12 extension).
The PKCS-12 standard is notorious for its peculiarities - see 
*PFX - How Not to Design a Crypto Protocol/Standard*
[[GUTPFX](#GUTPFX)]. 
If you do not have success with your target application, try changing the options.
In particular, using the `PKI_PFX_CLONE_KEY` option may cause problems if the target application cannot
decrypt the super-secure algorithm you've used to protect your private key 
(error messages about a missing cryptographic provider are a clue here).
That's why the default behaviour is to re-encrypt using the "standard" algorithm.

If you specify both a certificate and a private key, 
their RSA keys must match or a `PKI_NO_MATCH_ERROR` error will occur.
The PKCS-12 file will be protected using the specified *szPassword*, which must match the password 
for the encrypted private key file, if included. 
The password is optional for the case where there is just a certificate, but is required
if you need the certificate to be encrypted. 
If you don't use a password for a cert-only file, just enter an empty password
when importing the PFX into Windows. 

 If you use the `PKI_KEY_FORMAT_PEM` option, the output file will be in PEM format with the
first line `"-----BEGIN PKCS12-----"`.
Be warned, Windows does not recognise such a file as a valid PFX/PKCS-12 format!

> † The difference between the OpenSSL and Microsoft forms 
> is that the Microsoft form has a "preferredAbsent" NULL parameter added to the message digest object for "sha1" 
> and uses 8 instead of 20 bytes for the MacData salt. 
> Both combinations are perfectly valid according to the [PKCS12](#PKCS12) specification.

### Example

This example uses Bob's X.509 certificate and encrypted private key file to create a pkcs-12 file
and then verifies the signature.
The resulting file should be importable into Windows Certficate Manager or Mozilla with an exportable private key.

```

Dim strOutputFile As String
Dim strCertFile As String
Dim strKeyFile As String
Dim strPassword As String
Dim nRet As Long

strOutputFile = "Bob1.pfx"
strCertFile = "BobRSASignByCarl.cer"
strKeyFile = "BobPrivRSAEncrypt.p8e"
strPassword = "password"

' Given Bob's certificate and encrypted private key file (with password "password"),
' create a PKCS-12 (pfx/p12) file.
nRet = PFX_MakeFile(strOutputFile, strCertFile, strKeyFile, strPassword, "Bob's ID", 0)
Debug.Print "PFX_MakeFile returns " & nRet

' Now verify that the signature is OK
nRet = PFX_VerifySig(strOutputFile, strPassword, 0)
Debug.Print "PFX_VerifySig returns " & nRet

' Clean up
Call WIPE_String(strPassword, Len(strPassword))

```

Both functions should return zero.

The next example uses Carl's X.509 certificate to create a "certificate-only" pkcs-12 file.
This is useful for importing the certificate into Mozilla/Firefox.
Enter a blank password when importing.

```

Dim strOutputFile As String
Dim strCertFile As String
Dim strKeyFile As String
Dim nRet As Long

strOutputFile = "CarlNoKey.p12"
strCertFile = "CarlRSASelf.cer"

' Given Carl's certificate only,
' create a PKCS-12 (pfx/p12) file with no private key.
nRet = PFX_MakeFile(strOutputFile, strCertFile, "", "", "Carl's ID", 0)
Debug.Print "PFX_MakeFile returns " & nRet

```

The next example in C/C++ creates a pkcs-12 file in PEM format, 
using key and certificate data passed as strings.

```

long nRet;
char *outfile = "bob-pemfull.p12";
char *pfile;

char *password = "password";
char *epkstr = /* From BobPrivRSAEncrypt.p8e */
"-----BEGIN ENCRYPTED PRIVATE KEY-----""\n"
"MIICojAcBgoqhkiG9w0BDAEDMA4ECFolTdEnFcG+AgIH0ASCAoBUZJEzzH//"
"TRl5ieAHPo9q1eoMlYQu6j/eF8iIMNQ/eUp41iQIXqt9gcO2YdU5ah+ooMu4"
"ef1+yMN0buWUKFLgyUTyoYdg3O8XrCB6GhCCPeTXYvt6vYs4w85HHaXMZdfz"
"6dXAq3ratOVGq0PYg9dF0nI5T6Yd8S29TX4ceWyhNVG9yXAQhsRO1mMlS1tw"
"aTtxME7OSsQXe4mFgqGiCTwmNA183VqXdXP+1D2IrpI2zN+JfmTvOQIQ0iU8"
"ZuqBDMDRm8M/60uh2RlrfLqaIXKlF1V9PddijM6ORu8FFyPfaXkwZ7VsuvRS"
"Iijpf9PNDh4J+E0Vy1lsc6r4RrZWHdc4kKwKpYalE45wME14sbvh+WCZmFfd"
"D/pLZM8Or/IVHGYPFbpoAZwy+bmsjjOH/dBg6q1CY8mme9dnCBVLfXoZXTTk"
"o9TOSFw4Tmd/YEH2yPylT78hw+ThNsNmG2PwUX+5yTFoI7PQA8oBg6sN4kbP"
"tuRSo1fcB9RqJEO5hhqo+xAoMdhlHWdbIXOcEa1S8zLisJmgVrdAHJz6PPBl"
"3LVe1LHZ/oOD8rxeal8GTTCLk4onhjr7IT+DipMJendcjIgyok5I14DiKmjt"
"UPL10bt+0XkRVCIM0jma80YIGs4OMgRdW4u4n4lzJ0c1pxbvQvz8LY65OLcI"
"M+6VqJCH360iN1CSLRbVBg6HqjMNEthEXExKh/b95u+sVd4qPINmsnD1DwTd"
"4vkWx1zM4T+sKdz2GnBrjNRu2nJ4Nqe/krxDEKvcowh0eNllS/J86LhLYFFg"
"z/JKcqq20+GPSaQALvVXK7mVKljZcKEI6YQKQMgt5+amnDixhbvppSn/my1o"
"0kG3"
"-----END ENCRYPTED PRIVATE KEY-----";
char *certstr = /* From BobRSASignByCarl.cer */ 
"-----BEGIN CERTIFICATE-----""\n"
"MIICJzCCAZCgAwIBAgIQRjRrx4AAVrwR024uzV1x0DANBgkqhkiG9w0BAQUFADAS"
"MRAwDgYDVQQDEwdDYXJsUlNBMB4XDTk5MDkxOTAxMDkwMloXDTM5MTIzMTIzNTk1"
"OVowETEPMA0GA1UEAxMGQm9iUlNBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB"
"gQCp4WeYPznVX/Kgk0FepnmJhcg1XZqRW/sdAdoZcCYXD72lItA1hW16mGYUQVzP"
"t7cIOwnJkbgZaTdt+WUee9mpMySjfzu7r0YBhjY0MssHA1lS/IWLMQS4zBgIFEjm"
"Txz7XWDE4FwfU9N/U9hpAfEF+Hpw0b6Dxl84zxwsqmqn6wIDAQABo38wfTAMBgNV"
"HRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIFIDAfBgNVHSMEGDAWgBTp4JAnrHggeprT"
"TPJCN04irp44uzAdBgNVHQ4EFgQU6PS4Z9izlqQq8xGqKdOVWoYWtCQwHQYDVR0R"
"BBYwFIESQm9iUlNBQGV4YW1wbGUuY29tMA0GCSqGSIb3DQEBBQUAA4GBAHuOZsXx"
"ED8QIEyIcat7QGshM/pKld6dDltrlCEFwPLhfirNnJOIh/uLt359QWHh5NZt+eIE"
"VWFFvGQnRMChvVl52R1kPCHWRbBdaDOS6qzxV+WBfZjmNZGjOd539OgcOyncf1EH"
"l/M28FAK3Zvetl44ESv7V+qJba3JiNiPzyvT"
"-----END CERTIFICATE-----";

nRet = PFX_MakeFile(outfile, certstr, epkstr, password, "Bob's friendly ID", PKI_KEY_FORMAT_PEM);
if (nRet != 0) disp_error(nRet);
assert(nRet == 0);
printf("Created file '%s'\n", outfile);

pfile = outfile;
nRet = PFX_VerifySig(pfile, password, 0);
if (nRet != 0) disp_error(nRet);
assert(nRet == 0);
printf("Verified file '%s'\n", pfile);

```

### See Also

[PFX_VerifySig](#PFX_VerifySig)
[RSA_GetPrivateKeyFromPFX](#RSA_GetPrivateKeyFromPFX)
[RSA_ReadPrivateKeyFromPFX](#RSA_ReadPrivateKeyFromPFX)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PFX_VerifySig"></a>PFX_VerifySig
---------------------------------------

Verifies the signature in a pkcs-12 file.

### VBA/VB6 Syntax

`Public Declare Function PFX_VerifySig Lib "diCrPKI.dll" 
    (ByVal strPfxFile As String, ByVal strPassword As String, 
    ByVal nOptions As Long) As Long`

`nRet = PFX_VerifySig(strPfxFile, strPassword, nOptions)`

### C/C++ Syntax

`long __stdcall PFX_VerifySig(const char *szFileName, const char *szPassword, long nOptions);`

### Parameters

*szFileName*
:   [in] specifies the PKCS-12 filename to be checked.

*szPassword*
:   [in] containing the password.

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

[Pfx.SignatureIsValid Method](#M_Pfx_SignatureIsValid)  

### Python Equivalent

static [Pfx.sig_is_valid](https://cryptosys.net/pki/pydocpki/class-stubs/Pfx.html#cryptosyspki.Pfx.sig_is_valid "External link")(pfxfile, password)

### Remarks

Just checks that the MacData signature is OK using the given password. Makes no other checks.
The PFX file can be in either BER-encoded binary or PEM format. 
You can also pass the data directly as a [PEM string](#pemstring) in the *szPfxFile* parameter.

*[New in v3.8]* If there is no MacData signature in the PFX file and the supplied *szPassword* is empty, it will 
consider that to be a "valid" signature and return zero.

### Example

See the example for [`PFX_MakeFile`](#PFX_MakeFile) above.

### See Also

[PFX_MakeFile](#PFX_MakeFile)
[RSA_GetPrivateKeyFromPFX](#RSA_GetPrivateKeyFromPFX)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PKI_CompileTime"></a>PKI_CompileTime
-------------------------------------------

Retrieves the date and time the toolkit executable was last compiled.

### VBA/VB6 Syntax

`Public Declare Function PKI_CompileTime Lib "diCrPKI.dll" 
    (ByVal strCompiledOn As String, ByVal nStrLen As Long) As Long`

`nRet = PKI_CompileTime(strCompiledOn, nStrLen)`

### C/C++ Syntax

`long __stdcall PKI_CompileTime(char *szOutput, long nOutChars);`

### Parameters

*szOutput*
:   [out] to receive the date and time string.

*nOutChars*
:   [in] specifying the maximum length of the string to be copied.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`pkiCompileTime`](#VB_pkiCompileTime)() As String

### .NET Equivalent

[General.CompileTime Method](#M_General_CompileTime)  

### C++ (STL) Equivalent

static std::string [dipki::Gen::CompileTime](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_gen.html#a732f1c215c41715dae749f05ef1e5e7c "External link") ()

### Python Equivalent

static [Gen.compile_time](https://cryptosys.net/pki/pydocpki/class-stubs/Gen.html#cryptosyspki.Gen.compile_time "External link")()

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

### Example (VBA core function)

```

Dim nLen As Long
Dim strCompiledOn As String

strCompiledOn = String(255, " ")
nLen = PKI_CompileTime(strCompiledOn, Len(strCompiledOn))
strCompiledOn = Left(strCompiledOn, nLen)
Debug.Print "PKI_CompileTime returns " & nLen & " [" & strCompiledOn & "]"

```

### Example (VBA wrapper function)

```

Debug.Print pkiCompileTime()
Debug.Print pkiModuleInfo()
Debug.Print pkiModuleName()
Debug.Print pkiPlatform()

```

### See Also

[PKI_Version](#PKI_Version)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PKI_ErrorCode"></a>PKI_ErrorCode
---------------------------------------

Returns the error code of the *first* error that occurred
when calling the last function.

### VBA/VB6 Syntax

`Public Declare Function PKI_ErrorCode Lib "diCrPKI.dll" () As Long`

`nRet = PKI_ErrorCode()`

### C/C++ Syntax

`long __stdcall PKI_ErrorCode(void);`

### Parameters

None.

### Returns (VBA/C)

Returns the [error code](#errorcodes) for the *first* error that occurred
when calling the last function, or zero if no error occurred.
This may be different from the error code returned by the function itself if more than one error occurred
during the call to the function. 

### VBA Wrapper Syntax

Public Function [`pkiErrorCode`](#VB_pkiErrorCode)() As Long

### .NET Equivalent

[General.ErrorCode Method](#M_General_ErrorCode)  

### Python Equivalent

static [Gen.error_code](https://cryptosys.net/pki/pydocpki/class-stubs/Gen.html#cryptosyspki.Gen.error_code "External link")()

### Remarks

The value returned is always a non-negative integer.

For example, a call to CMS_MakeEnvData with one invalid X.509 certificate out of
three would return 2 indicating two successful recipients. 
A call to [`PKI_ErrorCode()`](#PKI_ErrorCode) will
indicate the error code for the invalid certificate. 
[PKI_LastError()](#PKI_LastError) should have a more detailed error message.

### Example

```

   Dim nErrCode as Long
   nErrCode = PKI_ErrorCode()

```

### See Also

[PKI_LastError](#PKI_LastError)
[PKI_ErrorLookup](#PKI_ErrorLookup)
[Error codes](#errorcodes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PKI_ErrorLookup"></a>PKI_ErrorLookup
-------------------------------------------

Retrieves the error message associated with a given error code.

### VBA/VB6 Syntax

`Public Declare Function PKI_ErrorLookup Lib "diCrPKI.dll" 
    (ByVal strOutput As String, ByVal nOutChars As Long, ByVal nErrCode As Long) As Long`

`nRet = PKI_ErrorLookup(strOutput, nOutChars, nErrCode)`

### C/C++ Syntax

`long __stdcall PKI_ErrorLookup(char *szOutput, long nOutChars, long nErrCode);`

### Parameters

*szOutput*
:   [out] to receive error message.

*nOutChars*
:   [in] specifying the maximum length of the string to be copied.

*nErrCode*
:   [in] specifying the error code for which the message is required.

### Returns (VBA/C)

The number of characters that have been set in *szOutput*.
If the function is called with *nOutChars* set to zero or *szOutput* as NULL, the return value is the number of characters
in the error message.

### VBA Wrapper Syntax

Public Function [`pkiErrorLookup`](#VB_pkiErrorLookup) (nErrCode As Long) As String

### .NET Equivalent

[General.ErrorLookup Method](#M_General_ErrorLookup)  

### C++ (STL) Equivalent

static std::string [dipki::Err::ErrorLookup](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_err.html#ad218a5ca4591b58f1b0cf2a1a853f402 "External link") (int errCode)

### Python Equivalent

static [Gen.error_lookup](https://cryptosys.net/pki/pydocpki/class-stubs/Gen.html#cryptosyspki.Gen.error_lookup "External link")(n)

### Remarks

Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length of the output string.
ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The error message will never be longer than 127 characters (`PKI_MAX_ERRORLOOKUP_CHARS`). 

### Example (VBA core function)

```

Dim nLen As Long
Dim nErrCode As Long
Dim strErrMsg As String * 128

nErrCode = 25
nLen = PKI_ErrorLookup(strErrMsg, Len(strErrMsg), nErrCode)
Debug.Print "ErrorLookup(" & nErrCode & ")=" & Left(strErrMsg, nLen)

```

This should return

```

ErrorLookup(25)=Certificate issuer error

```

### Example (VBA wrapper function)

```

Dim nErrCode As Long
For nErrCode = 1 To 11
    Debug.Print nErrCode & " = " & pkiErrorLookup(nErrCode)
Next

```

### See Also

[PKI_ErrorCode](#PKI_ErrorCode)
[Error codes](#errorcodes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PKI_FormatErrorMessage"></a>PKI_FormatErrorMessage
---------------------------------------------------------

Return a formatted error message string for the last error.

### VBA/VB6 Syntax

No direct call from VBA/VB6. Use [`errFormatErrorMessage`](#VB_errFormatErrorMessage)

### C/C++ Syntax

`long __stdcall PKI_FormatErrorMessage(char *szOutput, long nOutChars, long nErrCode, const char *szUserMsg);`

### Parameters

*szOutput*
:   [out] Buffer to receive output string.

*nOutChars*
:   [in] Maximum length of output string in bytes.

*nErrCode*
:   [in] Error code returned by last call (or zero if no code available).

*szUserMsg*
:   [in] Optional user message to add.

### Returns (VBA/C)

The number of characters that have been set in *szOutput*.

### .NET Equivalent

[General.FormatErrorMessage Method](#M_General_FormatErrorMessage)  

### C++ (STL) Equivalent

static std::string [dipki::Err::FormatErrorMessage](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_err.html#a27fe49e87703af2c7935028497bbadde "External link") (int errCode=0, const std::string &userMsg="")

### Remarks

This is a combination of [PKI_ErrorLookup](#PKI_ErrorLookup), [PKI_ErrorCode](#PKI_ErrorCode) and [PKI_LastError](#PKI_LastError) 
to give a complete formatted error message, for example

```

ERROR (11): Value out of range (OUT_OF_RANGE_ERROR)
ERROR: User message! (11): Value out of range (OUT_OF_RANGE_ERROR)
ERROR (21): No match found (NO_MATCH_ERROR): (1) Cannot open input file (OPEN_ERROR): Private key does not match any certificate in list

```

The equivalent functions in other languages are written independently and will give similar but not identical outputs.

The error message will never be longer than 1023 characters plus the length of any user message.
In the raw ANSI C function you *can* query the expected length, but it is recommended to write directly to a fixed size buffer, as in the example below.

### Example (C core function)

```

char szErrMsg[1024];
long errcode = 11;
PKI_FormatErrorMessage(szErrMsg, sizeof(szErrMsg) - 1, errcode, "User message!");
printf("%s\n", szErrMsg);

```

```

ERROR: User message! (11): Value out of range (OUT_OF_RANGE_ERROR)

```

### See Also

[PKI_ErrorLookup](#PKI_ErrorLookup)
[PKI_ErrorCode](#PKI_ErrorCode)
[PKI_LastError](#PKI_LastError)
[Error codes](#errorcodes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PKI_LastError"></a>PKI_LastError
---------------------------------------

Retrieves the last error message set by the toolkit.

### VBA/VB6 Syntax

`Public Declare Function PKI_LastError Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long) As Long`

`nRet = PKI_LastError(strOutput, nOutChars)`

### C/C++ Syntax

`long __stdcall PKI_LastError(char *szOutput, long nOutChars);`

### Parameters

*szOutput*
:   [out] to receive last error message.

*nOutChars*
:   [in] specifying the maximum length of the string to be copied.

### Returns (VBA/C)

If the preceding function call before calling `PKI_LastError`
was successful, the return value is
zero indicating no error; otherwise it is the number of characters that have been set in *szOutput*.

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. 
Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. 
ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

### VBA Wrapper Syntax

Public Function [`pkiLastError`](#VB_pkiLastError)() As String

### .NET Equivalent

[General.LastError Method](#M_General_LastError)  

### C++ (STL) Equivalent

static std::string [dipki::Err::LastError](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_err.html#a8df1f51e1ffacd29e58a610c0a5ae58d "External link") ()

### Python Equivalent

static [Gen.last_error](https://cryptosys.net/pki/pydocpki/class-stubs/Gen.html#cryptosyspki.Gen.last_error "External link")()

### Remarks

Not all functions set the error message string. 
The error message will never be longer than 511 characters. 

### Example (VBA/C core function)

Sample C function to obtain the last error message.

```

/** Display error codes and corresponding messages.
@param nRet Error code returned by last function.
*/
static void disp_error(long nRet)
{
    long errcode;
    char lasterrmsg[PKI_MAX_LASTERROR_CHARS + 1] = { 0 };
    char errlookupmsg[PKI_MAX_ERRORLOOKUP_CHARS + 1] = { 0 };
    // Get error message that occurred when calling last function (if any)
    PKI_LastError(lasterrmsg, sizeof(lasterrmsg) - 1);
    // Get error code for first error that occurred (may be different from nRet)
    errcode = PKI_ErrorCode();
    // Lookup message for error code
    if (errcode != 0)
        PKI_ErrorLookup(errlookupmsg, sizeof(errlookupmsg), errcode);
    else
        PKI_ErrorLookup(errlookupmsg, sizeof(errlookupmsg), nRet);
    // Display error details
    printf("ERROR Returned=%ld/Code=%ld: %s", nRet, errcode, errlookupmsg);
    // If we had a last error message, show it
    if (lasterrmsg[0])
        printf(": %s\n", lasterrmsg);
    else
        printf("\n");
}

```

### Example (VBA wrapper function)

```

Dim s As String
' Valid function call, no error
s = hashHexFromHex("616263", PKI_HASH_SHA1)
Debug.Print "SHA1('abc')=" & s
' No error, so expecting empty string
Debug.Print "LastError='" & pkiLastError() & "'"
' Force an error
s = rsaFromXMLString("BADSTRING")
Debug.Print "rsaFromXMLString(ERROR) returns '" & s & "'"
Debug.Print "LastError='" & pkiLastError() & "'"

```

```

SHA1('abc')=a9993e364706816aba3e25717850c26c9cd0d89d
LastError=''
rsaFromXMLString(ERROR) returns ''
LastError='Cannot find valid RSAKeyValue or RSAKeyPair element'

```

### See Also

[PKI_ErrorCode](#PKI_ErrorCode)
[PKI_ErrorLookup](#PKI_ErrorLookup)
[Error codes](#errorcodes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PKI_LicenceType"></a>PKI_LicenceType
-------------------------------------------

Returns the ASCII value of the licence type.

### VBA/VB6 Syntax

`Public Declare Function PKI_LicenceType Lib "diCrPKI.dll" 
    (ByVal nReserved As Long) As Long`

`nRet = PKI_LicenceType(nReserved)`

### C/C++ Syntax

`long __stdcall PKI_LicenceType(long nOptions);`

### Parameters

*nOptions*
:   [in] not used in this release. Specify zero.

### Returns (VBA/C)

Returns the ASCII value of the licence type, either "D" (68, 0x44) for the Developer Version
or "T" (84, 0x54) for the Trial Version.

### VBA Wrapper Syntax

Public Function [`pkiLicenceType`](#VB_pkiLicenceType) (Optional nOptions As Long = 0) As String

### .NET Equivalent

[General.LicenceType Method](#M_General_LicenceType)  

### C++ (STL) Equivalent

static std::string [dipki::Gen::LicenceType](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_gen.html#a740d056f996720c32bb48d6c9a80883a "External link") ()

### Python Equivalent

static [Gen.licence_type](https://cryptosys.net/pki/pydocpki/class-stubs/Gen.html#cryptosyspki.Gen.licence_type "External link")()

### Remarks

Note the Australian/English spelling of `Licence'.

### Example

```

Dim nRet As Long
nRet = PKI_LicenceType(0)
Debug.Print "PKI_LicenceType is " & Chr(nRet)

```

```

PKI_LicenceType is D

```

### See Also

[PKI_Version](#PKI_Version)
[PKI_CompileTime](#PKI_CompileTime)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PKI_ModuleInfo"></a>PKI_ModuleInfo
-----------------------------------------

Get additional information about the core DLL module.

### VBA/VB6 Syntax

`Public Declare Function PKI_ModuleInfo Lib "diCrPKI.dll" 
    (ByVal strName As String, ByVal nStrLen As Long, ByVal nOptions As Long) As Long`

`nRet = PKI_ModuleInfo(strName, nStrLen, 0)`

### C/C++ Syntax

`long __stdcall PKI_ModuleInfo(char *szOutput, long nOutChars, long nOptions);`

### Parameters

*szOutput*
:   [out] Buffer to receive output string.

*nOutChars*
:   [in] Maximum length of output string in bytes.

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`pkiModuleInfo`](#VB_pkiModuleInfo) (Optional nOptions As Long = 0) As String

### .NET Equivalent

[General.ModuleInfo Method](#M_General_ModuleInfo)  

### Example (VBA core function)

```

Dim nLen As Long
Dim strModuleInfo As String

nLen = PKI_ModuleInfo("", 0, 0)
If nLen > 0 Then
    strModuleInfo = String(nLen, " ")
    nLen = PKI_ModuleInfo(strModuleInfo, nLen, 0)
    strModuleInfo = Left(strModuleInfo, nLen)
    Debug.Print "PKI_ModuleInfo returns " & nLen & " [" & strModuleInfo & "]"
Else
    Debug.Print "Error " & nLen & " with PKI_ModuleInfo"
End If

```

```

PKI_ModuleInfo returns 26 [Licensed Developer Edition]

```

### Example (VBA wrapper function)

```

Debug.Print pkiCompileTime()
Debug.Print pkiModuleInfo()
Debug.Print pkiModuleName()
Debug.Print pkiPlatform()

```

[[Contents](#topofpage)] [[Index](#index)]

<a id="PKI_ModuleName"></a>PKI_ModuleName
-----------------------------------------

Retrieves the name of the current process's module.

### VBA/VB6 Syntax

`Public Declare Function PKI_ModuleName Lib "diCrPKI.dll" 
    (ByVal strName As String, ByVal nStrLen As Long, ByVal nOptions As Long) As Long`

`nRet = PKI_ModuleName(strName, nStrLen, 0)`

### C/C++ Syntax

`long __stdcall PKI_ModuleName(char *szOutput, long nOutChars, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive the name of the module.

*nOutChars*
:   [in] specifying the maximum length of the string to be copied.

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`pkiModuleName`](#VB_pkiModuleName) (Optional nOptions As Long = 0) As String

### .NET Equivalent

[General.ModuleName Method](#M_General_ModuleName)  

### C++ (STL) Equivalent

static std::string [dipki::Gen::ModuleName](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_gen.html#a1dab5a1f9481bc2e9d03b241707c8b41 "External link") ()

### Python Equivalent

static [Gen.module_name](https://cryptosys.net/pki/pydocpki/class-stubs/Gen.html#cryptosyspki.Gen.module_name "External link")()

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

If using the Win32 DLL in the system folder on a 64-bit system, 
Windows will return `"C:\WINDOWS\SYSTEM32\diCrPKI.dll"` when the DLL file path is actually 
`"C:\WINDOWS\SYSWOW64\diCrPKI.dll"`. 
Use `[PKI_Platform](#PKI_Platform)` to find out exactly which DLL is being used.

### Example (VBA core function)

```

Dim nLen As Long
Dim strModuleName As String

nLen = PKI_ModuleName("", 0, 0)
If nLen > 0 Then
    strModuleName = String(nLen, " ")
    nLen = PKI_ModuleName(strModuleName, nLen, 0)
    strModuleName = Left(strModuleName, nLen)
    Debug.Print "PKI_ModuleName returns " & nLen & " [" & strModuleName & "]"
Else
    Debug.Print "Error " & nLen & " with PKI_ModuleName"
End If

```

On our W10 system, this produces the output:

```

PKI_ModuleName returns 31 [C:\WINDOWS\SYSTEM32\diCrPKI.dll]

```

### Example (VBA wrapper function)

```

Debug.Print pkiCompileTime()
Debug.Print pkiModuleInfo()
Debug.Print pkiModuleName()
Debug.Print pkiPlatform()

```

### See Also

[PKI_Platform](#PKI_Platform)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PKI_Platform"></a>PKI_Platform
-------------------------------------

Gets the platform the core DLL was compiled for.

### VBA/VB6 Syntax

`Public Declare Function PKI_Platform Lib "diCrPKI.dll" 
    (ByVal strOutput As String, ByVal nOutChars As Long) As Long`

`nRet = PKI_Platform(strOutput, nOutChars)`

### C/C++ Syntax

`long __stdcall PKI_Platform(char *szOutput, long nOutChars);`

### Parameters

*szOutput*
:   [out] to receive output, either "Win32" or "X64".

*nOutChars*
:   [in] specifying the maximum length of the string to be copied.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`pkiPlatform`](#VB_pkiPlatform)() As String

### .NET Equivalent

[General.Platform Method](#M_General_Platform)  

### C++ (STL) Equivalent

static std::string [dipki::Gen::Platform](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_gen.html#af2e8acdc25d91b79ba5603088108f984 "External link") ()

### Python Equivalent

static [Gen.core_platform](https://cryptosys.net/pki/pydocpki/class-stubs/Gen.html#cryptosyspki.Gen.core_platform "External link")()

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

### Example (VBA wrapper function)

```

Debug.Print pkiCompileTime()
Debug.Print pkiModuleInfo()
Debug.Print pkiModuleName()
Debug.Print pkiPlatform()

```

### See Also

[PKI_ModuleName](#PKI_ModuleName)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PKI_PowerUpTests"></a>PKI_PowerUpTests
---------------------------------------------

Carries out on demand the full set of power-up tests automatically performed by the toolkit
when first powered up (i.e. when the DLL is first attached to the process).

### VBA/VB6 Syntax

`Public Declare Function PKI_PowerUpTests Lib "diCrPKI.dll" 
    (ByVal nOptions As Long) As Long`

`nRet = PKI_PowerUpTests(nOptions)`

### C/C++ Syntax

`long __stdcall PKI_PowerUpTests(long nOptions);`

### Parameters

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful, returns zero;
otherwise it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

[General.PowerUpTests Method](#M_General_PowerUpTests)  

### Remarks

This is an optional function. Unlike the tests carried out on actual power-up, this function does
not cause the DLL to quit. If errors do occur, an error event will be recorded in the Application event log
for NT+ operating systems or in an error log file on W9x systems. 
For more information on error logging after a self-test error, see [Self Tests](#selftests).
Users are warned not to use the toolkit if an error has
occurred after using this optional test. In such an event, please contact us. 

### Example

```

    Dim nRet As Long
    
    nRet = PKI_PowerUpTests(0)
    Debug.Print "PKI_PowerUpTests returns " & nRet

```

### See Also

[Self Tests](#selftests)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PKI_Version"></a>PKI_Version
-----------------------------------

Retrieves the release version number.

### VBA/VB6 Syntax

`Public Declare Function PKI_Version Lib "diCrPKI.dll" 
    (ByVal nReserved1 As Long, ByVal nReserved2 As Long) As Long`

`nRet = PKI_Version(0, 0)`

### C/C++ Syntax

`long __stdcall PKI_Version(void *nReserved1, void *nReserved2);`

### Parameters

*nReserved1*
:   [in] ignored in version 2.8 and above - use 0.

*nReserved2*
:   [in] ignored in version 2.8 and above - use 0.

### Returns (VBA/C)

Version number as an integer in form
`Major*100*100 + Minor*100 + Revision`.
For example, version 20.1.2 would return `200102`.
If this function fails, it means the toolkit is not installed or the library cannot be found.

### VBA Wrapper Syntax

Public Function [`pkiVersion`](#VB_pkiVersion)() As Long

### .NET Equivalent

[General.Version Method](#M_General_Version)  

### C++ (STL) Equivalent

static int [dipki::Gen::Version](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_gen.html#a5274e15a8183189f52b300e807037756 "External link") ()

### Python Equivalent

static [Gen.version](https://cryptosys.net/pki/pydocpki/class-stubs/Gen.html#cryptosyspki.Gen.version "External link")()

### Remarks

The arguments *nReserved1* and *nReserved2* are ignored.

### Example

```

Dim nRet As Long
nRet = PKI_Version(0, 0)
Debug.Print "PKI_Version returns " & nRet
' PKI_Version returns 200301

```

### See Also

[PKI_LicenceType](#PKI_LicenceType)
[PKI_CompileTime](#PKI_CompileTime)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PRF_Bytes"></a>PRF_Bytes
-------------------------------

Generate output bytes using a pseudorandom function (PRF).

### VBA/VB6 Syntax

`Public Declare Function PRF_Bytes Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByRef lpMessage As Byte, ByVal nMsgLen As Long, ByRef lpKey As Byte, ByVal nKeyLen As Long, ByVal strCustom As String, ByVal nOptions As Long) As Long`

`nRet = PRF_Bytes(abOutput(0), nOutBytes, abMessage(0), nMsgLen, abKey(0), nKeyLen, strCustom, nOptions)
' Note the "(0)" after the byte array parameters`

### C/C++ Syntax

`long __stdcall PRF_Bytes(unsigned char *lpOutput, long nOutBytes, const void *lpMessage, long nMsgLen, const void *lpKey, long nKeyLen, const char *szCustom, long nOptions);`

### Parameters

*lpOutput*
:   [out] byte buffer to receive the output.

*nOutBytes*
:   [in] size of output buffer in bytes.

*lpMessage*
:   [in] byte array containing the input data.

*nMsgLen*
:   [in] length of the input data in bytes.

*lpKey*
:   [in] byte array containing the key.

*nKeyLen*
:   [in] length of the key in bytes.

*szCustom*
:   [in] customization string (optional).

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_KMAC_128` to use KMAC128 (KMAC with SHAKE128)  

`PKI_KMAC_256` to use KMAC256 (KMAC with SHAKE256).

### Returns (VBA/C)

If successful, the return value is the number of bytes in the output;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`prfBytes`](#VB_prfBytes) (nBytes As Long, lpMessage() As Byte, lpKey() As Byte, nOptions As Long, Optional szCustom As String = "") As Byte()

### .NET Equivalent

[Prf.Bytes Method](#M_Prf_Bytes)  

### C++ (STL) Equivalent

static bvec_t [dipki::Prf::Bytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_prf.html#ad1500746341457d180a3b9ba73424030 "External link") (int numBytes, const bvec_t &message, const bvec_t &key, PrfAlg prfalg, const std::string &customStr="")

### Python Equivalent

static [Prf.bytes](https://cryptosys.net/pki/pydocpki/class-stubs/Prf.html#cryptosyspki.Prf.bytes "External link")(numbytes, msg, key, prfalg, customstring="")

### Remarks

The output buffer *lpOutput* must exist. It will be filled with exactly *nOutBytes* bytes.
Note there is no zero option for *nOptions*: a valid option flag must be specified.
For KMAC, the default customization string *szCustom* is the empty string `""`.

### Example (VBA core function)

```

Dim strKeyHex As String
Dim strMsgHex As String
Dim nOutBits As Long
Dim nOutBytes As Long
Dim abMAC() As Byte
Dim abMsg() As Byte
Dim abKey() As Byte
Dim nMsgLen As Long
Dim nKeyLen As Long
Dim strCustom As String
Dim strOK As String
Dim nRet As Long

' Ref: `KMAC_samples.pdf` "Secure Hashing - KMAC-Samples" 2017-02-27
' <https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/KMAC_samples.pdf>

' Sample #2
' Input in hex form
strKeyHex = "404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F"
strMsgHex = "00010203"
nOutBits = 256
strCustom = "My Tagged Application"
strOK = "3B1FBA963CD8B0B59E8C1A6D71888B7143651AF8BA0A7070C0979E2811324AA5"
' Convert to byte array form
abKey = cnvBytesFromHexStr(strKeyHex)
abMsg = cnvBytesFromHexStr(strMsgHex)
nKeyLen = UBound(abKey) + 1
nMsgLen = UBound(abMsg) + 1

' Required output size
nOutBytes = (nOutBits / 8)
ReDim abMAC(nOutBytes - 1)
nRet = PRF_Bytes(abMAC(0), nOutBytes, abMsg(0), nMsgLen, abKey(0), nKeyLen, strCustom, PKI_KMAC_128)
If nRet > 0 Then
    Debug.Print "KMAC=" & cnvHexStrFromBytes(abMAC)
    Debug.Print "OK  =" & strOK
Else
   Debug.Print "Error code " & nRet
End If

```

This should result in output as follows:

```

KMAC=3B1FBA963CD8B0B59E8C1A6D71888B7143651AF8BA0A7070C0979E2811324AA5
OK  =3B1FBA963CD8B0B59E8C1A6D71888B7143651AF8BA0A7070C0979E2811324AA5

```

### Example (VBA wrapper function)

```

Dim lpPrf() As Byte
Dim lpMsg() As Byte
Dim lpKey() As Byte
lpKey = cnvFromHex("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F")
lpMsg = cnvFromHex("00010203")
' NB order of parameters (szCustom <=> nOptions).
lpPrf = prfBytes(256 \ 8, lpMsg, lpKey, PKI_KMAC_128, "My Tagged Application")
Debug.Print "KMAC=" & cnvToHex(lpPrf)
Debug.Print "OK  =3B1FBA963CD8B0B59E8C1A6D71888B7143651AF8BA0A7070C0979E2811324AA5"

```

### See Also

[`XOF_Bytes`](#XOF_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PWD_Prompt"></a>PWD_Prompt
---------------------------------

Prompts for a password in a dialog box.

### VBA/VB6 Syntax

`Public Declare Function PWD_Prompt Lib "diCrPKI.dll" 
    (ByVal strPassword As String, ByVal nPwdLen As Long, ByVal strCaption As String) As Long`

`nRet = PWD_Prompt(strPassword, nPwdLen, strCaption)`

### C/C++ Syntax

`long __stdcall PWD_Prompt(char *szPassword, long nPwdLen, const char *szCaption);`

### Parameters

*szPassword*
:   [out] to receive the password entered by the user.

*nPwdLen*
:   [in] specifying the maximum length of the string to be received.

*szCaption*
:   [in] specifying a caption for the dialog box (optional).

### Returns (VBA/C)

If the user enters a password in the dialog box and clicks "OK", 
the return value is the length of the password entered in bytes. This could be zero.
If the user clicks "Cancel", the return value is -1.

### VBA Wrapper Syntax

Public Function [`pwdPrompt`](#VB_pwdPrompt) (Optional szCaption As String = "", Optional szPrompt As String = "") As String

### .NET Equivalent

[Pwd.Prompt Method](#M_Pwd_Prompt)  

### C++ (STL) Equivalent

static std::string [dipki::Pwd::Prompt](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_pwd.html#ac74618d08be72b6f619310ab30a6e03b "External link") (const std::string &caption, const std::string &prompt="", int maxChars=1024)

### Remarks

Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length of the output string.
ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The password string is limited to 255 characters. It's up to the developer to protect the secrecy of the password
once it's been entered: 
see [`WIPE_Data()`](#WIPE_Data).

### Example (VBA core function)

This wrapper function can be used to return a password entered by the user in a dialog box.
Note it does not distinguish between an empty password and the user clicking "Cancel".

```

Public Function pwdPrompt(Optional sCaption As String) As String
    Dim sPassword As String
    Dim nLen As Long
    
    nLen = 255
    sPassword = String(nLen, " ")
    nLen = PWD_Prompt(sPassword, nLen, sCaption)
    If nLen < 0 Then
        Exit Function
    ElseIf nLen > 0 Then
        pwdPrompt = Left$(sPassword, nLen)
    End If
    ' Clean up local variable
    Call WIPE_String(sPassword, nLen)
End Function

```

Example to prompt for a password in C:

```

long pwdlen;
char password[256];

pwdlen = PWD_Prompt(password, sizeof(password)-1, "Test");
if (pwdlen >= 0)
    printf("Password entered=[%s]\n", password);
else
    printf("No password entered\n");

/* ... use password ... */

WIPE_Data(password, pwdlen);

```

### See Also

[PWD_PromptEx](#PWD_PromptEx)

[[Contents](#topofpage)] [[Index](#index)]

<a id="PWD_PromptEx"></a>PWD_PromptEx
-------------------------------------

Prompts for a password in a dialog box with option to change prompt wording.

### VBA/VB6 Syntax

`Public Declare Function PWD_PromptEx Lib "diCrPKI.dll" 
    (ByVal strPassword As String, ByVal nPwdLen As Long, ByVal strCaption As String,
    ByVal strPrompt As String, ByVal nOptions As Long) As Long`

`nRet = PWD_PromptEx(strPassword, nPwdLen, strCaption, strPrompt, nOptions)`

### C/C++ Syntax

`long __stdcall PWD_PromptEx(char *szPassword, long nPwdLen, const char *szCaption, const char *szPrompt, long nOptions);`

### Parameters

*szPassword*
:   [out] to receive the password entered by the user.

*nPwdLen*
:   [in] specifying the maximum length of the string to be received.

*szCaption*
:   [in] specifying a caption for the dialog box (optional).

*szPrompt*
:   [in] specifying the prompt (default="Enter password:").

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If the user enters a password in the dialog box and clicks "OK", 
the return value is the length of the password entered in bytes. This could be zero.
If the user clicks "Cancel", the return value is -1.

### .NET Equivalent

[Pwd.Prompt Method](#M_Pwd_Prompt)  

### Python Equivalent

static [Pwd.prompt](https://cryptosys.net/pki/pydocpki/class-stubs/Pwd.html#cryptosyspki.Pwd.prompt "External link")(caption="", prompt="")

### Remarks

See [`PWD_Prompt()`](#PWD_Prompt).

### Example

Example of `PWD_PromptEx`:

```

Dim strPassword As String * 511
Dim nLen As Long

nLen = PWD_PromptEx(strPassword, Len(strPassword), _
    "Demo of PWD_PromptEx", "Type secret phrase:", 0)
' Do something with the password...
If nLen > 0 Then
    Debug.Print "Password entered=" &amp; Left(strPassword, nLen)
ElseIf nLen &lt; 0 Then
    Debug.Print "User cancelled"
Else
    Debug.Print "Empty password entered"
End If
' Clean up
Call WIPE_String(strPassword, nLen)
strPassword = ""

```

### See Also

[PWD_Prompt](#PWD_Prompt)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RNG_Bytes"></a>RNG_Bytes
-------------------------------

Generates a random set of byte data suitable for cryptographic keys.

### VBA/VB6 Syntax

`Public Declare Function RNG_Bytes Lib "diCrPKI.dll" 
    (ByRef lpData As Byte, ByVal nDataLen As Long, ByVal strSeed As String, 
    ByVal nSeedLen As Long) As Long`

`nRet = RNG_Bytes(lpData(0), nDataLen, strSeed, nSeedLen)`

### C/C++ Syntax

`long __stdcall RNG_Bytes(unsigned char *lpOutput, long nOutBytes, const void *lpSeed, long nSeedLen);`

### Parameters

*lpOutput*
:   [out] array to receive the random data.

*nOutBytes*
:   [in] specifying the required length in bytes.

*lpSeed*
:   [in] containing "user-supplied entropy" to be used by the random number
generator. Specify an empty string ("") or NULL  to ignore.

*nSeedLen*
:   [in] specifying the length of the seed string.

### Returns (VBA/C)

If successful, the return value is zero.
If the parameters are invalid, it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`rngBytes`](#VB_rngBytes) (nBytes As Long) As Byte()

### .NET Equivalent

[Rng.Bytes Method](#M_Rng_Bytes_Int32) (Int32)  
[Rng.Bytes Method](#M_Rng_Bytes_Int32Byte) (Int32, Byte)  
[Rng.Bytes Method](#M_Rng_Bytes_Int32String) (Int32, String)  

### C++ (STL) Equivalent

static bvec_t [dipki::Rng::Bytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rng.html#a387b33340abf4e1233426494059f61a9 "External link") (int n)

### Python Equivalent

static [Rng.bytestring](https://cryptosys.net/pki/pydocpki/class-stubs/Rng.html#cryptosyspki.Rng.bytestring "External link")(n)

### Remarks

The maximum number of random bytes that can be requested in one call is 65,536 (64 kB). 
If you need more (!), make repeated calls.
VB6/VBA users: for historical reasons, the seed parameter is passed as a `String` type
and may contain any 8-bit value including the NUL (zero) value. 
The length of the seed must be specified (set *nSeedLen* as zero to ignore).

 
If the RNG fails its FIPS-140 continuous test, the DLL process will be terminated. There is no option to avoid this, 
but the chances of such a failure under normal conditions are absolutely miniscule
 - about 1 in 9 quintillion (billion billion billion).
See [Random Number Generator](#rnginfo) for more information on the RNG, entropy,
and its compliance with the relevant standards.

### Example (VBA core function)

```

Dim abData() As Byte
Dim nDataLen As Long

nDataLen = 16
ReDim abData(nDataLen - 1)
Call RNG_Bytes(abData(0), nDataLen, "", 0)
Debug.Print cnvHexStrFromBytes(abData)

```

### Example (VBA wrapper function)

```

Dim i As Integer
For i = 1 To 10
    Debug.Print cnvHexStrFromBytes(rngBytes(32))
Next
```

### See Also

[RNG_BytesWithPrompt](#RNG_BytesWithPrompt)
[RNG_Number](#RNG_Number)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RNG_BytesWithPrompt"></a>RNG_BytesWithPrompt
---------------------------------------------------

Generates a random set of byte data suitable for cryptographic keys
with a prompt for the user to enter random keystrokes and mouse movements.

### VBA/VB6 Syntax

`Public Declare Function RNG_BytesWithPrompt Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutputLen As Long, ByVal strPrompt As String, ByVal nOptions As Long) As Long`

`nRet = RNG_BytesWithPrompt(lpOutput(0), nOutputLen, strPrompt, nSeedLen)`

### C/C++ Syntax

`long __stdcall RNG_BytesWithPrompt(unsigned char *lpOutput, long nOutBytes, const char *szPrompt, long nOptions);`

### Parameters

*lpOutput*
:   [out] array to receive the random data.

*nOutBytes*
:   [in] specifying the required length in bytes.

*szPrompt*
:   [in] specifying an (optional) prompt for the dialog. 
	Specify an empty string ("") or NULL to use the default dialog.

*nOptions*
:   [in] option flags:  

`PKI_DEFAULT` (0) for default options  

`PKI_RNG_STRENGTH_112` to make user generate an estimated 112 bits of security (default)  

`PKI_RNG_STRENGTH_128` to make user generate an estimated 128 bits of security 

`PKI_RNG_STRENGTH_192` to make user generate an estimated 192 bits of security 

`PKI_RNG_STRENGTH_256` to make user generate an estimated 256 bits of security

### Returns (VBA/C)

If successful, the return value is zero.
If the parameters are invalid, it returns a negative [error code](#errorcodes).

### .NET Equivalent

[Rng.BytesWithPrompt Method](#M_Rng_BytesWithPrompt_Int32Rng_Strength) (Int32, Rng.Strength)  

[Rng.BytesWithPrompt Method](#M_Rng_BytesWithPrompt_Int32StringRng_Strength) (Int32, String, Rng.Strength)  

### Python Equivalent

static [Rng.bytes_with_prompt](https://cryptosys.net/pki/pydocpki/class-stubs/Rng.html#cryptosyspki.Rng.bytes_with_prompt "External link")(n, strength=Strength.BITS_112, prompt='')

### Remarks

Once started, there is no way to abandon the dialog that prompts the user except by terminating the process.
Some applications may not handle the GUI dialog. Make your own tests to check.
The maximum number of random bytes that can be requested in one call is 65,536 (64 kB).
See [Random Number Generator](#rnginfo) for more information on the RNG 
and its compliance with the relevant standards.

### Example

```

Dim abData() As Byte
Dim nDataLen As Long

' Allocate byte array for 16 bytes
nDataLen = 16
ReDim abData(nDataLen - 1)

' Default prompt with default 112-bit security strength
Call RNG_BytesWithPrompt(abData(0), nDataLen, "", 0)
Debug.Print cnvHexStrFromBytes(abData)

' User-selected prompt with 128-bit security strength
Call RNG_BytesWithPrompt(abData(0), nDataLen, "Our own prompt: type until done...", PKI_RNG_STRENGTH_128)
Debug.Print cnvHexStrFromBytes(abData)

```

### See Also

[RNG_Bytes](#RNG_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RNG_Guid"></a>RNG_Guid
-----------------------------

Generate a random 36-character Global Unique IDentifier (GUID) string.

### VBA/VB6 Syntax

`Public Declare Function RNG_Guid Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal nOptions As Long) As Long`

`nRet = RNG_Guid(strOutput, nOutChars, nOptions)`

### C/C++ Syntax

`long __stdcall RNG_Guid(char *szOutput, long nOutChars, long nOptions);`

### Parameters

*szOutput*
:   [out] String buffer to receive output.

*nOutChars*
:   [in] Maximum number of characters to be received.

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string (always 36); otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`rngGuid`](#VB_rngGuid)() As String

### .NET Equivalent

[Rng.Guid Method](#M_Rng_Guid)  

### C++ (STL) Equivalent

static std::string [dipki::Rng::Guid](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rng.html#a7388a8609da4617ca54662fe6093fd1a "External link") ()

### Python Equivalent

static [Rng.guid](https://cryptosys.net/pki/pydocpki/class-stubs/Rng.html#cryptosyspki.Rng.guid "External link")()

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

A *Global Unique IDentifier* (GUID) is also called a version 4 *Universally Unique IDentifier* (UUID) and is defined in section 4.4 of [[RFC4122](#RFC4122)].
The output is always a 36-character string of the form "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" where 'x' is a hexadecimal digit `[0-9a-f]`.
The constant `PKI_RNG_GUID_CHARS` equal to 36 is defined for convenience.
It is an error (`SHORT_BUF_ERROR`) if the output buffer is too short.

### Example (VBA core function)

```

Dim strGuid As String
strGuid = String(PKI_RNG_GUID_CHARS, " ")
Call RNG_Guid(strGuid, Len(strGuid), 0)
Debug.Print strGuid

```

The output will be different each time. For example

```

9d67804a-4d8f-40c2-8f7d-5f05f90cb228
85291113-b97f-4d30-8892-76d556801372
fc4272a5-c731-4b96-9c7c-450fad9a29c0

```

### Example (VBA wrapper function)

```

Dim i As Integer
For i = 1 To 5
    Debug.Print rngGuid()
Next
```

### See Also

[[Contents](#topofpage)] [[Index](#index)]

<a id="RNG_Initialize"></a>RNG_Initialize
-----------------------------------------

Initializes the RNG generator with a seed file.

### VBA/VB6 Syntax

`Public Declare Function RNG_Initialize Lib "diCrPKI.dll" (ByVal strSeedFile As String, ByVal nOptions As Long) As Long`

`nRet = RNG_Initialize(strSeedFile, nOptions)`

### C/C++ Syntax

`long __stdcall RNG_Initialize(const char *szSeedFile, long nOptions);`

### Parameters

*szSeedFile*
:   [in] specifying a seed file. May be the empty string `""`.

*nOptions*
:   [in] option flags:  

`PKI_DEFAULT` (0) for default options  

`PKI_RNG_NO_INTEL_DRNG` to turn off support for Intel(R) DRNG for the current session.

### Returns (VBA/C)

If successful, the return value is zero; otherwise it returns a nonzero [error code](#errorcodes).
If `""` is passed for *szSeedFile*, it returns the support status for Intel DRNG (see Remarks). 

### VBA Wrapper Syntax

Public Function [`rngInitialize`](#VB_rngInitialize) (szSeedFile As String) As Long  
Public Function [`rngInitializeEx`](#VB_rngInitializeEx) (Optional nOptions As Long = 0) As Long

### .NET Equivalent

[Rng.Initialize Method](#M_Rng_Initialize)  

[Rng.InitializeEx Method](#M_Rng_InitializeEx)  

### C++ (STL) Equivalent

static int [dipki::Rng::Initialize](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rng.html#a49d9a9c8d333976acfb17551bd22886d "External link") (const std::string &seedFile)  

static int [dipki::Rng::InitializeEx](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rng.html#a2c709f37337b06ac4fd16c25c7682ffd "External link") (Opts opts=Opts::Default)

static [Rng.initialize_ex](https://cryptosys.net/pki/pydocpki/class-stubs/Rng.html#cryptosyspki.Rng.initialize_ex "External link")(opts=0)

### Python Equivalent

`static [Rng.initialize](https://cryptosys.net/pki/pydocpki/class-stubs/Rng.html#cryptosyspki.Rng.initialize "External link")(seedfilename)`

static [Rng.initialize_ex](https://cryptosys.net/pki/pydocpki/class-stubs/Rng.html#cryptosyspki.Rng.initialize_ex "External link")(opts=0)

### Remarks

A seed file maintains the entropy state between sessions. 
If the seed file does not exist, it will be created, using any existing entropy. The file must be writable by the user. 
File locking is used to prevent interference from simultaneous use by others.
The seed file is automatically updated by this procedure. Any existing file will be overwritten without warning.

**Intel(R) DRNG support:** *[New in v22.1]* Pass an empty string `""` for *szSeedFile* to query support for 
Intel(R) Digital Random Number Generator (DRNG) on your system (and add an extra 256 bits of entropy, if available).
If supported, the return value is a positive integer (1,2,3), 
otherwise it returns the error code `PRNG_ERR_NOTAVAIL` (-214).
See [Intel(R) DRNG](#inteldrng).

Alternatively, use the option `PKI_RNG_NO_INTEL_DRNG` to turn off support for Intel(R) DRNG for the current session. 
You might use this if calls to Intel(R) DRNG are causing problems on your system.

### Examples

This example shows how to initialize the RNG with a seed file, generate some random data, and then update the seed file.

```

Dim strSeedFile As String
Dim nRet As Long
Dim abData() As Byte
Dim nDataLen As Long
Dim i As Integer

strSeedFile = "seed.dat"
' 1. Initialize
nRet = RNG_Initialize(strSeedFile, 0)
Debug.Print "RNG_Initialize('" & strSeedFile & "') returns " & nRet & " (expecting 0)"

' 2. Generate some random data
nDataLen = 24
ReDim abData(nDataLen - 1)
For i = 1 To 3
    Call RNG_Bytes(abData(0), nDataLen, "", 0)
    Debug.Print cnvHexStrFromBytes(abData)
Next

' 3. Update the seed file
nRet = RNG_UpdateSeedFile(strSeedFile, 0)
Debug.Print "RNG_UpdateSeedFile('" & strSeedFile & "') returns " & nRet & " (expecting 0)"

```

```

RNG_Initialize('seed.dat') returns 0 (expecting 0)
79654D8DA3D30468B95B820E3C5615838A765CA666C68A9D
EB2DA20FC86CC797BCB3D26C9E663736E616EF99DEB56C21
5A3DB035BD374E57649AEE367A7E0156A3045AE0111D47EC
RNG_UpdateSeedFile('seed.dat') returns 0 (expecting 0)

```

This example demonstrates support for Intel(R) DRNG

```

Dim n As Long
n = RNG_Initialize("", 0)  ' Query support for Intel(R) DRNG
Debug.Print "RNG_Initialize() returns " & n & " (If > 0 Intel(R) DRNG support available)"
' Explicitly turn off support...
n = RNG_Initialize("", PKI_RNG_NO_INTEL_DRNG)  ' Turns off Intel(R) DRNG support
Debug.Print "RNG_Initialize(PKI_RNG_NO_INTEL_DRNG) returns " & n & " (expected -ve)"
n = RNG_Initialize("", 0)  ' Now query again
Debug.Print "RNG_Initialize() returns " & n & " (expected -ve)"

```

```

RNG_Initialize() returns 3 (If > 0 Intel(R) DRNG support available)
RNG_Initialize(PKI_RNG_NO_INTEL_DRNG) returns -214 (expected -ve)
RNG_Initialize() returns -214 (expected -ve)

```

In practice, you should test for Intel(R) DRNG support before calling any RNG function. If supported, then the generator will have been seeded with sufficient entropy. 
If not supported, then use a seed file.

```

Dim n As Long
n = rngInitializeEx()
If n <= 0 Then
    ' Use a seed file
    n = rngInitialize("seed.dat")
End If
' Do work...
Dim abKey() As Byte
abKey = rngBytes(32)
Debug.Print cnvToHex(abKey)
' ...etc
' At end of session, update the seed file
n = RNG_UpdateSeedFile("seed.dat", 0)

```

### See Also

[RNG_MakeSeedFile](#RNG_MakeSeedFile)
[RNG_UpdateSeedFile](#RNG_UpdateSeedFile)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RNG_MakeSeedFile"></a>RNG_MakeSeedFile
---------------------------------------------

Creates a new seed file suitable for use with 
	[`RNG_Initialize()`](#RNG_Initialize).

### VBA/VB6 Syntax

`Public Declare Function RNG_MakeSeedFile Lib "diCrPKI.dll" (ByVal strSeedFile As String, ByVal strPrompt As String, ByVal nOptions As Long) As Long`

`nRet = RNG_MakeSeedFile(strSeedFile, strPrompt, nOptions)`

### C/C++ Syntax

`long __stdcall RNG_MakeSeedFile(const char *szSeedFile, const char *szPrompt, long nOptions);`

### Parameters

*szSeedFile*
:   [in] specifying the seed file to be created.

*szPrompt*
:   [in] specifying an (optional) prompt for the dialog. 
	Specify an empty string ("") or NULL to use the default dialog.

*nOptions*
:   [in] option flags:  

`PKI_DEFAULT` (0) for default options  

`PKI_RNG_STRENGTH_112` to make user generate an estimated 112 bits of security (default)  

`PKI_RNG_STRENGTH_128` to make user generate an estimated 128 bits of security 

`PKI_RNG_STRENGTH_192` to make user generate an estimated 192 bits of security 

`PKI_RNG_STRENGTH_256` to make user generate an estimated 256 bits of security

### Returns (VBA/C)

If successful, the return value is zero; otherwise it returns a nonzero [error code](#errorcodes). 

### .NET Equivalent

[Rng.MakeSeedFile Method](#M_Rng_MakeSeedFile)  

### Python Equivalent

static [Rng.make_seedfile](https://cryptosys.net/pki/pydocpki/class-stubs/Rng.html#cryptosyspki.Rng.make_seedfile "External link")(seedfilename, strength=Strength.BITS_128, prompt='')

### Remarks

This uses a dialog window and expects the user to type in random keystrokes. 
Such a GUI interface may not be appropriate in all circumstances.
A new seed file is always created. Any existing file with the same name will be overwritten without warning.
Alternatively, use the command-line program, `PkiMkRngSeed.exe`, provided in the distribution
to make a new seed file *[updated in v22.1]*.

### Example

```

Dim strSeedFile As String
Dim nRet As Long

strSeedFile = "seed.dat"
nRet = RNG_MakeSeedFile(strSeedFile, "Making a new seed file: hit random keys until done...", PKI_RNG_STRENGTH_128)
Debug.Print "RNG_MakeSeedFile('" & strSeedFile & "') returns " & nRet & " (expecting 0)"

```

### See Also

[RNG_Initialize](#RNG_Initialize)
[RNG_UpdateSeedFile](#RNG_UpdateSeedFile)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RNG_Number"></a>RNG_Number
---------------------------------

Returns an integer selected at random between specified limits.

### VBA/VB6 Syntax

`Public Declare Function RNG_Number Lib "diCrPKI.dll"
    (ByVal nLower As Long, ByVal nUpper As Long) As Long`

`nRandom = RNG_Number(nLower, nUpper)`

### C/C++ Syntax

`long __stdcall RNG_Number(long nLower, long nUpper);`

### Parameters

*nLower*
:   [in] specifying a lower limit.

*nUpper*
:   [in] specifying an upper limit.

### Returns (VBA/C)

An integer selected at random from the set {*nLower*, ..., *nUpper*}.

### .NET Equivalent

[Rng.Number Method](#M_Rng_Number)  

[Rng.Octet Method](#M_Rng_Octet)  

### C++ (STL) Equivalent

static int [dipki::Rng::Number](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rng.html#a07289bae32a6ddd89da54a4c20a3c85d "External link") (int lower, int upper)

static [Rng.octet](https://cryptosys.net/pki/pydocpki/class-stubs/Rng.html#cryptosyspki.Rng.octet "External link")()

### Python Equivalent

`static [Rng.number](https://cryptosys.net/pki/pydocpki/class-stubs/Rng.html#cryptosyspki.Rng.number "External link")(lower, upper)`

static [Rng.octet](https://cryptosys.net/pki/pydocpki/class-stubs/Rng.html#cryptosyspki.Rng.octet "External link")()

### Remarks

The number returned is an integer selected at random with uniform probability from the set 
{*nLower*, ..., *nUpper*}.

### Example

This will generate 5 random numbers in the range between -1 million and +1 million:

```

Dim i As Integer
For i = 1 To 5
    Debug.Print RNG_Number(-1000000, 1000000)
Next

```

This will generate 16 random bits in [0,1]:

```

Dim i As Integer
For i = 1 To 16
    Debug.Print RNG_Number(0, 1);
Next
Debug.Print

```

```

0  0  0  1  0  0  1  1  0  1  1  1  0  0  1  1 

```

A function to generate a random octet (byte).

```

Public Function rngOctet() As Byte
    rngOctet = RNG_Number(0, 255)
End Function

```

This will generate 8 random octets (bytes):

```

Dim i As Integer
For i = 1 To 8
    Debug.Print rngOctet();
Next
Debug.Print

```

```

6  131  87  118  57  252  240  33 

```

### See Also

[RNG_Bytes](#RNG_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RNG_String"></a>RNG_String
---------------------------------

Generates a string of random characters (classic VB6/VBA only).

### VBA/VB6 Syntax

`Public Declare Function RNG_String Lib "diCrPKI.dll" Alias "RNG_Bytes" 
    (ByVal strData As String, ByVal nDataLen As Long, ByVal strSeed As String, 
    ByVal nSeedLen As Long) As Long`

`nRet = RNG_String(strData, nDataLen, strSeed, nSeedLen)`

### C/C++ Syntax

`[Not applicable]`

### Parameters

*szData*
:   [out] to receive the random data.

*nDataLen*
:   [in] specifying the required length in bytes.

*szSeed*
:   [in] containing a user-specified seed to be used by the random number
generator. Specify an empty string ("") to ignore.

*nSeedLen*
:   [in] specifying the length of the seed string.

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

Not applicable

### Remarks

@deprecated.
This is an alias for classic Visual Basic (VB6/VBA) users only.

The output string may contain characters with value zero 
(and possibly traces of nuts). Storing binary information in a string is bad practice.
This function was provided for one specific purpose and is deprecated.
See [Random Number Generator](#rnginfo) for more information on the RNG and seeds.

### Example

### See Also

[RNG_Bytes](#RNG_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RNG_StringWithPrompt"></a>RNG_StringWithPrompt
-----------------------------------------------------

Generate a string of random characters with a prompt (classic VB6/VBA only). 

### VBA/VB6 Syntax

`Public Declare Function RNG_StringWithPrompt Lib "diCrPKI.dll" Alias "RNG_BytesWithPrompt" 
(ByVal strData As String, ByVal nDataLen As Long, ByVal strPrompt As String, ByVal nOptions As Long) As Long`

`nRet = RNG_StringWithPrompt(strData, nDataLen, strPrompt, nOptions)`

### C/C++ Syntax

`[Not applicable]`

### Parameters

*szData*
:   [out] to receive the random data.

*nDataLen*
:   [in] specifying the required length in bytes.

*szPrompt*
:   [in] specifying an (optional) prompt for the dialog. 
	Specify an empty string ("") or NULL to use the default dialog.

*nOptions*
:   [in] option flags:  

`PKI_DEFAULT` (0) for default options  

`PKI_RNG_STRENGTH_112` to make user generate an estimated 112 bits of security (default)  

`PKI_RNG_STRENGTH_128` to make user generate an estimated 128 bits of security 

`PKI_RNG_STRENGTH_192` to make user generate an estimated 192 bits of security 

`PKI_RNG_STRENGTH_256` to make user generate an estimated 256 bits of security

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

Not applicable

### Remarks

@deprecated.
This is an alias for classic Visual Basic (VB6/VBA) users only.

The output string may contain characters with value zero 
(and possibly traces of nuts).
See [Random Number Generator](#rnginfo) for more information on the RNG and seeds.

### Example

### See Also

[RNG_BytesWithPrompt](#RNG_BytesWithPrompt)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RNG_Test"></a>RNG_Test
-----------------------------

Carries out a NIST SP800-90 health check and FIPS140-2 statistical tests on the random number generator.

### VBA/VB6 Syntax

`Public Declare Function RNG_Test Lib "diCrPKI.dll" (ByVal strFileName As String, ByVal nOptions As Long) As Long`

`nRet = RNG_Test(strFileName, nOptions)`

### C/C++ Syntax

`long __stdcall RNG_Test(const char *szFileOut, long nOptions);`

### Parameters

*szFileOut*
:   [in] (optional) specifying the test output file to be created.

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is zero; otherwise it returns a nonzero [error code](#errorcodes). 

### .NET Equivalent

[Rng.Test Method](#M_Rng_Test)  

### Remarks

This function carries out, on demand, the health testing procedure from section 11.3 of 
[[SP80090A](#SP80090A)] and the statistical tests for randomness from 
section 4.9.1 of the October 2001 version of FIPS-140-2 [[FIPS140](#FIPS140)].
The statistical test results and the 20,000-bit sample are written to a text file. 
Specify an empty (`""`) or NULL *szFileName* to avoid creating an output file and just
carry out the tests. The statistical tests have since been removed from FIPS-140-2, but we do them anyway.
If any tests fail, a nonzero error code will be returned.

### Example

```

Dim strFileName As String
Dim nRet As Long

strFileName = "pkiFips140.txt"
nRet = RNG_Test(strFileName, 0)
Debug.Print "RNG_Test('" & strFileName & "') returns " & nRet & " (expecting 0)"

```

### See Also

[RNG_Initialize](#RNG_Initialize)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RNG_TestDRBGVS"></a>RNG_TestDRBGVS
-----------------------------------------

Test the RNG for conformance to NIST SP800-90A using the relevant test specified in DRBGVS.

### VBA/VB6 Syntax

`Public Declare Function RNG_TestDRBGVS Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nMaxChars As Long, ByVal nReturnedBitsLen As Long, ByVal strEntropyInput As String, ByVal strNonce As String, ByVal strPersonalizationString As String, ByVal strAdditionalInput1 As String, ByVal strEntropyReseed As String, ByVal strAdditionalInputReseed As String, ByVal strAdditionalInput2 As String, ByVal nOptions As Long) As Long`

`nRet = RNG_TestDRBGVS(strOutput, nMaxChars, nReturnedBitsLen, strEntropyInput, strNonce, strPersonalizationString,  strAdditionalInput1, strEntropyReseed, strAdditionalInputReseed, strAdditionalInput2, nOptions)`

### C/C++ Syntax

`long __stdcall  RNG_TestDRBGVS(char *szOutput, long nMaxChars, long nReturnedBitsLen, const char *szEntropyInput, 
	const char *szNonce, const char *szPersonalizationString, const char *szAdditionalInput1, 
	const char *szEntropyReseed, const char *szAdditionalInputReseed, const char *szAdditionalInput2, long nOptions);`

### Parameters

*szOutput*

:   [out] to receive the ReturnedBits in hexadecimal format.

*nMaxChars*

:   [in] specifying the maximum number of hexadecimal characters to be received.

*nReturnedBitsLen*

:   [in] specifying the number of bits to be returned from each call to the generate function in the test.

*szEntropyInput*

:   [in] containing the EntropyInput value in hex format.

*szNonce*

:   [in] containing the Nonce value in hex format.

*szPersonalizationString*

:   [in] containing the PersonalizationString value in hex format.

*szAdditionalInput1*

:   [in] containing the first AdditionalInput value in hex format.

*szEntropyReseed*

:   [in] containing the EntropyReseed value in hex format.

*szAdditionalInputReseed*

:   [in] containing the AdditionalInputReseed value in hex format.

*szAdditionalInput2*

:   [in] containing the second AdditionalInput value in hex format.

*nOptions*

:   [in] Option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is the number of characters in the output string; 
otherwise it returns a negative [error code](#errorcodes).

### .NET Equivalent

[Rng.TestDrbgvs Method](#M_Rng_TestDrbgvs)  

### Python Equivalent

static [Rng.test_drbgvs](https://cryptosys.net/pki/pydocpki/class-stubs/Rng.html#cryptosyspki.Rng.test_drbgvs "External link")(returnedBitsLen, entropyInput, nonce, personalizationString, additionalInput1, entropyReseed, additionalInputReseed, additionalInput2)

### Remarks

The test procedure, the input values and the expected output are described in the [[DRBGVS](#DRBGVS)] document and associated test vectors. 
The relevant DRBG mechanism is `HMAC_DRBG SHA-512` without prediction resistance.
Use the empty string `""` to pass a zero-length input. All hex strings must have an even number of characters.

### Example

```

' drbgtestvectors/drbgvectors_pr_false/HMAC_DRBG.txt (line 22654)
' # CAVS 14.3
' # DRBG800-90A information for "drbg_pr"
' # Generated on Tue Apr 02 15:32:12 2013
Dim nRet As Long
Dim strOutput As String
Dim nMaxChars As Long
' Set input values in hex
Const nReturnedBitsLen As Long = 2048
Const strEntropyInput As String = "da740cbc36057a8e282ae717fe7dfbb245e9e5d49908a0119c5dbcf0a1f2d5ab"
Const strNonce As String = "46561ff612217ba3ff91baa06d4b5440"
Const strPersonalizationString As String = "fc227293523ecb5b1e28c87863626627d958acc558a672b148ce19e2abd2dde4"
Const strAdditionalInput1 As String = "b7998998eaf9e5d34e64ff7f03de765b31f407899d20535573e670c1b402c26a"
Const strEntropyReseed As String = "1d61d4d8a41c3254b92104fd555adae0569d1835bb52657ec7fbba0fe03579c5"
Const strAdditionalInputReseed As String = "b9ed8e35ad018a375b61189c8d365b00507cb1b4510d21cac212356b5bbaa8b2"
Const strAdditionalInput2 As String = "2089d49d63e0c4df58879d0cb1ba998e5b3d1a7786b785e7cf13ca5ea5e33cfd"
Const strExpectedBits = "5b70f3e4da95264233efbab155b828d4e231b67cc92757feca407cc9615a6608" & _
	"71cb07ad1a2e9a99412feda8ee34dc9c57fa08d3f8225b30d29887d20907d123" & _
	"30fffd14d1697ba0756d37491b0a8814106e46c8677d49d9157109c402ad0c24" & _
	"7a2f50cd5d99e538c850b906937a05dbb8888d984bc77f6ca00b0e3bc97b16d6" & _
	"d25814a54aa12143afddd8b2263690565d545f4137e593bb3ca88a37b0aadf79" & _
	"726b95c61906257e6dc47acd5b6b7e4b534243b13c16ad5a0a1163c0099fce43" & _
	"f428cd27c3e6463cf5e9a9621f4b3d0b3d4654316f4707675df39278d5783823" & _
	"049477dcce8c57fdbd576711c91301e9bd6bb0d3e72dc46d480ed8f61fd63811"

' Print output details
Debug.Print "# HMAC_DRBG options: SHA-512"
Debug.Print "[SHA-512]"
Debug.Print "[PredictionResistance = False]"
Debug.Print "[EntropyInputLen = " & Len(strEntropyInput) * 8 / 2 & "]"
Debug.Print "[NonceLen = " & Len(strNonce) * 8 / 2 & "]"
Debug.Print "[PersonalizationStringLen = " & Len(strPersonalizationString) * 8 / 2 & "]"
Debug.Print "[AdditionalInputLen = " & Len(strAdditionalInput1) * 8 / 2 & "]"
Debug.Print
Debug.Print "COUNT = 0"
Debug.Print "EntropyInput = " & strEntropyInput
Debug.Print "Nonce = " & strNonce
Debug.Print "PersonalizationString = " & strPersonalizationString
Debug.Print "AdditionalInput = " & strAdditionalInput1
Debug.Print "EntropyInputReseed = " & strEntropyReseed
Debug.Print "AdditionalInputReseed = " & strAdditionalInputReseed
Debug.Print "AdditionalInput = " & strAdditionalInput2

' Perform the DRBGVS test, dimensioning output string first
strOutput = String(nReturnedBitsLen * 2 / 8, " ")
nRet = RNG_TestDRBGVS(strOutput, Len(strOutput), nReturnedBitsLen, strEntropyInput, strNonce, _
	strPersonalizationString, strAdditionalInput1, _
	strEntropyReseed, strAdditionalInputReseed, strAdditionalInput2, 0)
Debug.Print "ReturnedBits = " & strOutput
Debug.Print "ExpectedBits = " & strExpectedBits
Debug.Assert strOutput = strExpectedBits

```

```

# HMAC_DRBG options: SHA-512
[SHA-512]
[PredictionResistance = False]
[EntropyInputLen = 256]
[NonceLen = 128]
[PersonalizationStringLen = 256]
[AdditionalInputLen = 256]

COUNT = 0
EntropyInput = da740cbc36057a8e282ae717fe7dfbb245e9e5d49908a0119c5dbcf0a1f2d5ab
Nonce = 46561ff612217ba3ff91baa06d4b5440
PersonalizationString = fc227293523ecb5b1e28c87863626627d958acc558a672b148ce19e2abd2dde4
AdditionalInput = b7998998eaf9e5d34e64ff7f03de765b31f407899d20535573e670c1b402c26a
EntropyInputReseed = 1d61d4d8a41c3254b92104fd555adae0569d1835bb52657ec7fbba0fe03579c5
AdditionalInputReseed = b9ed8e35ad018a375b61189c8d365b00507cb1b4510d21cac212356b5bbaa8b2
AdditionalInput = 2089d49d63e0c4df58879d0cb1ba998e5b3d1a7786b785e7cf13ca5ea5e33cfd
ReturnedBits = 5b70f3e4da95264233efbab155b828d4e231b67cc92757feca407cc9615a6608...
ExpectedBits = 5b70f3e4da95264233efbab155b828d4e231b67cc92757feca407cc9615a6608...

```

### See Also

[`RNG_Test`](#RNG_Test)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RNG_UpdateSeedFile"></a>RNG_UpdateSeedFile
-------------------------------------------------

Updates an RNG seed file.

### VBA/VB6 Syntax

`Public Declare Function RNG_UpdateSeedFile Lib "diCrPKI.dll" (ByVal strSeedFile As String, ByVal nOptions As Long) As Long`

`nRet = RNG_UpdateSeedFile(strSeedFile, nOptions)`

### C/C++ Syntax

`long __stdcall RNG_UpdateSeedFile(const char *szSeedFile, long nOptions);`

### Parameters

*szSeedFile*
:   [in] specifying the seed file to be updated.

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is zero; otherwise it returns a nonzero [error code](#errorcodes). 

### .NET Equivalent

[Rng.UpdateSeedFile Method](#M_Rng_UpdateSeedFile)  

### C++ (STL) Equivalent

static int [dipki::Rng::UpdateSeedFile](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rng.html#ac97be2de93aab03d4caee358b0410bd8 "External link") (const std::string &seedFile)

### Python Equivalent

static [Rng.update_seedfile](https://cryptosys.net/pki/pydocpki/class-stubs/Rng.html#cryptosyspki.Rng.update_seedfile "External link")(seedfilename)

### Remarks

This writes a fresh set of random data to the seed file.
The seed file must be writable by the user. Use this function at periodic intervals or when exiting your application.
If the file does not exist it will be created. Any existing file of the same name will be overwritten without warning. 

### Example

See the example in [`RNG_Initialize`](#RNG_Initialize).

### See Also

[RNG_Initialize](#RNG_Initialize)
[RNG_MakeSeedFile](#RNG_MakeSeedFile)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_CheckKey"></a>RSA_CheckKey
-------------------------------------

Checks if an RSA key is valid.

### VBA/VB6 Syntax

`Public Declare Function RSA_CheckKey Lib "diCrPKI.dll" 
    (ByVal strKeyString As String, 
    ByVal nOptions As Long) As Long`

`nRet = RSA_CheckKey(strKeyString, nOptions)`

### C/C++ Syntax

`long __stdcall RSA_CheckKey(const char *szKeyString, long nOptions);`

### Parameters

*szKeyString*
:   [in] containing the RSA public or private key in internal format

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is `PKI_VALID_PRIVATEKEY` (0) 
if the key is a valid private key, or `PKI_VALID_PUBLICKEY` (1) if the key is a public key;
otherwise it returns a negative [error code](#errorcodes).

### .NET Equivalent

[Rsa.CheckKey Method](#M_Rsa_CheckKey_String) (String)  
[Rsa.CheckKey Method](#M_Rsa_CheckKey_StringBuilder) (StringBuilder)  

### C++ (STL) Equivalent

static bool [dipki::Rsa::KeyIsPrivate](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a6978884750ddf44b09f4c71437034335 "External link") (const std::string &keyStr)

### Python Equivalent

static [Rsa.key_isprivate](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.key_isprivate "External link")(keystr)

### Remarks

If the key is a private key, the system carries out a pairwise check using a random message block to verify that the
key is a valid RSA key pair (the format used to store private keys contains both the public and private components).
Such a check cannot be carried out with a public key.

### Example

See [`RSA_FromXMLString`](#RSA_FromXMLString).

### See Also

[RSA_KeyBits](#RSA_KeyBits)
[RSA_KeyBytes](#RSA_KeyBytes)
[RSA_KeyHashCode](#RSA_KeyHashCode)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_DecodeMsg"></a>RSA_DecodeMsg
---------------------------------------

Decodes an EME or EMSA encoded message block according to PKCS#1
(EME = Encoding Method for Encryption, EMSA = Encoding Method for Signature with Appendix).

### VBA/VB6 Syntax

`Public Declare Function RSA_DecodeMsg Lib "diCrPKI.dll" 
    (ByRef lpOutput As Byte, ByVal nOutChars As Long,
    ByRef lpInput As Byte, ByVal nInputLen As Long,
    ByVal nOptions As Long) As Long`

`nRet = RSA_DecodeMsg(lpOutput(0), nOutputLen, lpInput(0), nInputLen, nOptions)`

### C/C++ Syntax

`long __stdcall RSA_DecodeMsg(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpInput, long nInputLen, long nOptions);`

### Parameters

*lpOutput*
:   [out] array to receive the decoded output.

*nOutBytes*
:   [in] specifying the maximum length of the output array.

*lpInput*
:   [in] array containing the data to be decoded.

*nInputLen*
:   [in] specifying the number of bytes in the input.

*nOptions*
:   [in] option flags.
Include one of the following:-  

`PKI_EME_PKCSV1_5` (0) to decode an 'Encoded Message for Encryption' block using PKCS#1 v1.5 method (default)  

`PKI_EME_OAEP` to decode an 'Encoded Message for Encryption' block using OAEP method  

`PKI_EMSIG_PKCSV1_5` to decode an `Encoded Message for Signature' block using PKCS#1 v1.5 method  

If you have selected `PKI_EMSIG_PKCSV1_5`, then you can add:  

`PKI_EMSIG_DIGINFO` to decode an 'Encoded Message for Signature' block 
and output the whole `DigestInfo` data instead of just the message digest.  

If you have selected `PKI_EME_OAEP`, then add one of these options to match the hash function used for EME-OAEP encoding:  

`PKI_HASH_SHA1` (0) to use SHA-1 (default).  

`PKI_HASH_SHA224` to use SHA-224  

`PKI_HASH_SHA256` to use SHA-256  

`PKI_HASH_SHA384` to use SHA-384  

`PKI_HASH_SHA512` to use SHA-512  

and, optionally, add:-  

`PKI_MGF_MGF1SHA1` to force the MGF hash function to be SHA-1 (default = same as encoding hash function set above)  

The encoding hash function and MGF hash function *must* match the hash functions used to encode the message.

Alternatively, ignore all the above and use the specialist option  

`PKI_EMSIG_ISO9796` to use the ISO9796-1 encoding for a signature. See 
[AUTACK messages and ISO/IEC 9796-1 signatures](#autackmsgs) for more details.

### Returns (VBA/C)

If successful, the return value is the number of bytes required to store the full output data. 
If an error occurs, it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`rsaDecodeMsg`](#VB_rsaDecodeMsg) (lpInput() As Byte, nOptions As Long) As Byte()

### .NET Equivalent

[Rsa.DecodeMsgForEncryption Method](#M_Rsa_DecodeMsgForEncryption)  

[Rsa.DecodeDigestForSignature Method](#M_Rsa_DecodeDigestForSignature)  

[Rsa.DecodeMsgIso9796 Method](#M_Rsa_DecodeMsgIso9796)  

static [Rsa.decode_msg_for_encryption](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.decode_msg_for_encryption "External link")(data, method=EME.PKCSV1_5)

### Python Equivalent

`static [Rsa.decode_digest_for_signature](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.decode_digest_for_signature "External link")(data, full_digestinfo=False)`

static [Rsa.decode_msg_for_encryption](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.decode_msg_for_encryption "External link")(data, method=EME.PKCSV1_5)

### Remarks

This function recovers the relevant data from an encoded message block according to the algorithms in PKCS#1.

Messages encoded for both encryption and signature using the PKCS#1 v1.5 method are self-contained: that is, they can be decoded with no further information other than the encoded message itself.
However, a message encoded using the OAEP method will be assumed by default to have been encoded using the default SHA-1 function for both the encoding hash algorithm and MGF hash algorithm.
If you used a different hash function when encoding you need to specify it explicitly in *nOptions*.

The algorithm **RSA-PSS** is not available for this function. Use [`SIG_VerifyData`](#SIG_VerifyData) instead.

#### Decoding an EME Block

The objective is to recover the original message data which is encoded in the block. 
Use either

```
nOptions = PKI_EME_PKCSV1_5
```

 or 

```
nOptions = PKI_EME_OAEP
```

You need to know which algorithm was used to create the block in the first place.

#### Decoding an EMSA Block

The objective is to verify that the encoded message digest hash matches the message digest hash of the original message.

*Note:* it is much simpler (and safer) to use the [`RSA_EncodeMsg()`](#RSA_EncodeMsg)
function on the original message
and then compare the result of that with the input block you have here. See [Raw RSA Techniques](#rawrsa).
The options here are included for advanced users.

There are two choices when decoding an EMSA block:

1. Extract the message digest bytes. Set

    ```
    nOptions = PKI_EMSIG_PKCSV1_5
    ```

2. Extract the whole `DigestInfo` bytes. 
Set

    ```
    nOptions = PKI_EMSIG_PKCSV1_5 + PKI_EMSIG_DIGINFO
    ```

    You might use this if you come across a hash algorithm that is not supported by this Toolkit. 
    Use this option to recover the entire
    `DigestInfo` and then inspect the bytes to work out what it is, using your knowledge of DER encoding.

Remember that the result of a decode operation for a signature is to compare the hash digest encoded in the signature with an independent digest of the original message.
If they match, the signature is verified.
To avoid an attacker exploiting flaws in the decoding operation, it is safer just to generate another EMSA block from the message and compare that directly. 

### Example (VBA core function)

```

    Dim abData() As Byte
    Dim abBlock() As Byte
    Dim abDigest() As Byte
    Dim abDigInfo() As Byte
    Dim nDataLen As Long
    Dim nBlockLen As Long
    Dim nLen As Long
    Dim nRet As Long
    Dim nOptions As Long
    
    ' 0. Create an encoded test block ready for for signing
    abData = StrConv("abc", vbFromUnicode)
    nDataLen = UBound(abData) - LBound(abData) + 1
    nBlockLen = 64
    ReDim abBlock(nBlockLen - 1)
    nRet = RSA_EncodeMsg(abBlock(0), nBlockLen, abData(0), nDataLen, PKI_EMSIG_PKCSV1_5)
    Debug.Print "BLOCK   =" & cnvHexStrFromBytes(abBlock)
    
    ' 1. Extract the message digest =SHA1("abc")
    nLen = RSA_DecodeMsg(0, 0, abBlock(0), nBlockLen, PKI_EMSIG_PKCSV1_5)
    If nLen < 0 Then MsgBox "Decryption Error": Exit Function
    Debug.Print "Message digest is " & nLen & " bytes long"
    ReDim abDigest(nLen - 1)
    nLen = RSA_DecodeMsg(abDigest(0), nLen, abBlock(0), nBlockLen, PKI_EMSIG_PKCSV1_5)
    Debug.Print "HASH    =" & cnvHexStrFromBytes(abDigest)
    
     ' 2. Extract the full DigestInfo data
    nOptions = PKI_EMSIG_PKCSV1_5 + PKI_EMSIG_DIGINFO
    nLen = RSA_DecodeMsg(0, 0, abBlock(0), nBlockLen, nOptions)
    If nLen < 0 Then MsgBox "Decryption Error": Exit Function
    Debug.Print "DigestInfo is " & nLen & " bytes long"
    ReDim abDigest(nLen - 1)
    nLen = RSA_DecodeMsg(abDigest(0), nLen, abBlock(0), nBlockLen, nOptions)
    Debug.Print "DIGINFO=" & cnvHexStrFromBytes(abDigest)

```

This should produce results like:

```

BLOCK  =0001FFFFFF...C26C9CD0D89D
Message digest is 20 bytes long
HASH   =A9993E364706816ABA3E25717850C26C9CD0D89D
DigestInfo is 35 bytes long
DIGINFO=3021300906052B0E03021A05000414A9993E364706816ABA3E25717850C26C9CD0D89D

```

### Example (VBA wrapper function)

```

Dim lpData() As Byte
Dim lpBlock() As Byte
Dim lpDecoded() As Byte
Dim nBlockLen As Long
nBlockLen = 512 \ 8

lpData = cnvBytesFromHexStr("DEADBEEF")

lpBlock = rsaEncodeMsg(nBlockLen, lpData, PKI_EME_PKCSV1_5)
Debug.Print cnvHexStrFromBytes(lpBlock)
lpDecoded = rsaDecodeMsg(lpBlock, PKI_EME_PKCSV1_5)
Debug.Print "DECODED=" & cnvHexStrFromBytes(lpDecoded)

lpBlock = rsaEncodeMsg(nBlockLen, lpData, PKI_EME_OAEP)
Debug.Print cnvHexStrFromBytes(lpBlock)
lpDecoded = rsaDecodeMsg(lpBlock, PKI_EME_OAEP)
Debug.Print "DECODED=" & cnvHexStrFromBytes(lpDecoded)

lpBlock = rsaEncodeMsg(nBlockLen, lpData, PKI_EMSIG_PKCSV1_5 Or PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpBlock)
lpDecoded = rsaDecodeMsg(lpBlock, PKI_EMSIG_PKCSV1_5)
Debug.Print "DECODED=" & cnvHexStrFromBytes(lpDecoded)

Debug.Print "DIGEST =" & hashHexFromBytes(lpData, PKI_HASH_SHA256)

```

### See Also

[RSA_EncodeMsg](#RSA_EncodeMsg)
[RSA_RawPublic](#RSA_RawPublic)
[RSA_RawPrivate](#RSA_RawPrivate)
[Raw RSA Techniques](#rawrsa)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_Decrypt"></a>RSA_Decrypt
-----------------------------------

Decrypt a message encrypted using an RSA encryption scheme.

### VBA/VB6 Syntax

`Public Declare Function RSA_Decrypt Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByRef lpInput As Byte, ByVal nInputLen As Long, ByVal strPrivateKeyFile As String, ByVal strPassword As String, ByVal strParameters As String, ByVal nOptions As Long) As Long`

`nRet = RSA_Decrypt(lpOutput(0), nOutBytes, lpInput(0), nInputLen, strPrivateKeyFile, strPassword, strParameters, nOptions)`

### C/C++ Syntax

`long __stdcall RSA_Decrypt(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpInput, long nInputLen, const char *szPrivateKeyFile, const char *szPassword, const char *szParameters, long nOptions);`

### Parameters

*lpOutput*
:   [out] byte array to receive the decrypted output.

*nOutBytes*
:   [in] maximum length of the output array.

*lpInput*
:   [in] byte array containing the data to be decrypted.

*nInputLen*
:   [in] length of input in bytes.

*szPrivateKeyFile*
:   [in] specifying the name of the private key file
	(or a string containing the key in [PEM format](#pemstring), or a valid internal private key string).

*szPassword*
:   [in] Password for encrypted private key, or `""` if password is not required.

*szParameters*
:   [in] For future use. Specify `""`.

*nOptions*
:   [in] option flags.
Include one of the following:-  

`PKI_EME_PKCSV1_5` (0) to decrypt using the RSAES-PKCS1-v1_5 encryption scheme (default).  

`PKI_EME_OAEP` to decrypt using the RSAES-OAEP encryption scheme.  

If you have selected `PKI_EME_OAEP`, then add one of these options to set the hash function used for EME-OAEP encoding:  

`PKI_HASH_SHA1` (0) to use SHA-1 (default).  

`PKI_HASH_SHA224` to use SHA-224  

`PKI_HASH_SHA256` to use SHA-256  

`PKI_HASH_SHA384` to use SHA-384  

`PKI_HASH_SHA512` to use SHA-512  

and, optionally, add:-  

`PKI_MGF_MGF1SHA1` to force the MGF hash function to be SHA-1 (default = same as encoding hash function set above)

### Returns (VBA/C)

If successful, the return value is the number of bytes required to store the full output data. If an error occurs, it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`rsaDecrypt`](#VB_rsaDecrypt) (lpInput() As Byte, szPrivateKeyFile As String, szPassword As String, nOptions As Long, Optional szParameters As String = "") As Byte()

### .NET Equivalent

[Rsa.Decrypt Method](#M_Rsa_Decrypt)  

### C++ (STL) Equivalent

static bvec_t [dipki::Rsa::Decrypt](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#af10a5292171c8e7388e1de5a0231ade4 "External link") (const bvec_t &data, const std::string &privateKeyFileOrString, const std::string &password="", EME method=EME::PKCSv1_5, HashAlg hashAlg=HashAlg::Sha1, AdvOpts advOpts=AdvOpts::Default)

### Python Equivalent

static [Rsa.decrypt](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.decrypt "External link")(data, prikeyfileorstring, password="", method=EME.PKCSV1_5, hashalg=HashAlg.SHA1, advopts=AdvOpts.DEFAULT)

### Remarks

Set *nOutBytes* to zero and/or *lpOutput* to 0 (or `NULL`) to return the required number of bytes.
The output will *always* be shorter than the input length.

For RSA-OAEP you must set the correct options to match the parameters used for the encryption. 
For more details see [RSA encryption and signature schemes](#rsaschemes).

### Example (VBA core function)

See [RSA_Encrypt](#RSA_Encrypt).

### Example (VBA wrapper function)

See example for VBA wrapper `rsaEncrypt` in [RSA_Encrypt](#RSA_Encrypt).

### See Also

[RSA_Encrypt](#RSA_Encrypt)
[RSA_DecodeMsg](#RSA_DecodeMsg)
[RSA_RawPrivate](#RSA_RawPrivate)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_EncodeMsg"></a>RSA_EncodeMsg
---------------------------------------

Creates an EME or EMSA encoded message block according to PKCS#1
(EME = Encoding Method for Encryption, EMSA = Encoding Method for Signature with Appendix).

### VBA/VB6 Syntax

`Public Declare Function RSA_EncodeMsg Lib "diCrPKI.dll" 
    (ByRef lpOutput As Byte, ByVal nOutputLen As Long,
    ByRef lpMessage As Byte, ByVal nMsgLen As Long,
    ByVal nOptions As Long) As Long`

`nRet = RSA_EncodeMsg(lpOutput(0), nOutputLen, lpMessage(0), nMsgLen, nOptions)`

### C/C++ Syntax

`long __stdcall RSA_EncodeMsg(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpInput, long nInputLen, long nOptions);`

### Parameters

*lpOutput*
:   [out] array to receive the encoded output.

*nOutBytes*
:   [in] specifying the maximum length of the output array.

*lpInput*
:   [in] array containing the message to be encoded (or the message digest).

*nInputLen*
:   [in] specifying the number of bytes in the message.

*nOptions*
:   [in] option flags.
Include one of the following:-  

`PKI_EME_PKCSV1_5` (0) to encode for encryption using PKCS#1 v1.5 method (RSAES-PKCS1-v1_5) (default)  

`PKI_EME_OAEP` to encode for encryption using OAEP method  

`PKI_EMSIG_PKCSV1_5` to encode for signature using PKCS#1 v1.5 method (RSASSA-PKCS1-v1_5)  

If you have selected `PKI_EMSIG_PKCSV1_5`, then add one of these options to set the hash function for the signature message digest:  

`PKI_HASH_SHA1` (0) to use SHA-1 (default).  

`PKI_HASH_SHA224` to use SHA-224  

`PKI_HASH_SHA256` to use SHA-256  

`PKI_HASH_SHA384` to use SHA-384  

`PKI_HASH_SHA512` to use SHA-512  

`PKI_HASH_MD5` to use MD5 [legacy, not recommended]  

`PKI_HASH_MD2` to use MD2 [legacy, definitely not recommended]  

and, optionally, add:-  

`PKI_EMSIG_DIGESTONLY` as a flag to pass the message digest only as input to-be-signed (default = pass entire message)  

If you have selected `PKI_EME_OAEP`, then add one of these options to set the hash function for EME-OAEP encoding:  

`PKI_HASH_SHA1` (0) to use SHA-1 (default).  

`PKI_HASH_SHA224` to use SHA-224  

`PKI_HASH_SHA256` to use SHA-256  

`PKI_HASH_SHA384` to use SHA-384  

`PKI_HASH_SHA512` to use SHA-512  

and, optionally, add:-  

`PKI_MGF_MGF1SHA1` to force the MGF hash function to be SHA-1 (default = same as encoding hash function set above)  

Alternatively, ignore all the above and use the specialist option  

`PKI_EMSIG_ISO9796` to use the ISO9796-1 encoding for a signature. See 
[AUTACK messages and ISO/IEC 9796-1 signatures](#autackmsgs) for more details.

### Returns (VBA/C)

If successful, the return value is zero; otherwise it returns a negative [error code](#errorcodes).
  
**CAUTION:** This function assumes you know the required length of the output. It does not return the length.

### VBA Wrapper Syntax

Public Function [`rsaEncodeMsg`](#VB_rsaEncodeMsg) (nBlockLen As Long, lpInput() As Byte, nOptions As Long) As Byte()

### .NET Equivalent

[Rsa.EncodeMsgForEncryption Method](#M_Rsa_EncodeMsgForEncryption)  

[Rsa.EncodeMsgForSignature Method](#M_Rsa_EncodeMsgForSignature)  

[Rsa.EncodeDigestForSignature Method](#M_Rsa_EncodeDigestForSignature)  

[Rsa.EncodeMsgIso9796 Method](#M_Rsa_EncodeMsgIso9796)  

static [Rsa.encode_msg_for_encryption](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.encode_msg_for_encryption "External link")(keybytes, message, method=EME.PKCSV1_5)

### Python Equivalent

`static [Rsa.encode_msg_for_signature](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.encode_msg_for_signature "External link")(keybytes, message, hashalg=HashAlg.SHA1, digest_only=False)`

static [Rsa.encode_msg_for_encryption](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.encode_msg_for_encryption "External link")(keybytes, message, method=EME.PKCSV1_5)

### Remarks

There are two distinct operations available here (a design decision that we regret, in hindsight). 
One operation creates an 'Encoded Message for Encryption' (EME) block which you would then encrypt with an RSA
public key using the [RSA_RawPublic()](#RSA_RawPublic) function. 
The other creates an 'Encoded Message for Signature with Appendix' (EMSA) block which you would then
sign by encrypting with an RSA private key using the  [RSA_RawPrivate()](#RSA_RawPrivate) function.

#### To Encode an EME Block

Set either

```
nOptions = PKI_EME_PKCSV1_5
```

 or 

```
nOptions = PKI_EME_OAEP
```

The default operation `PKI_EME_PKCSV1_5` will create an encoded EME message block according to
PKCS#1 v1.5. The `PKI_EME_OAEP` alternative uses a more secure algorithm 
(OAEP = Optimal Asymmetric Encryption Padding).

#### To Encode an EMSA Block

To encode the message "Hello world" ready for signing, use the `PKI_EMSIG_PKCSV1_5` option and set

```

nOptions = PKI_EMSIG_PKCSV1_5
abInput = StrConv("Hello world", vbFromUnicode)
nInputLen = UBound(abMessage) - LBound(abMessage) + 1

```

```

nOptions = PKI_EMSIG_PKCSV1_5;
input = "Hello world";
nInputLen = strlen(input);

```

If you need to be compatible with a legacy application that uses, say, MD5, add the hash flag to the option

```

nOptions = PKI_EMSIG_PKCSV1_5 + PKI_HASH_MD5

```

If you have already computed the message digest in byte array form, then pass this as input and set

```

nOptions = PKI_EMSIG_PKCSV1_5 + PKI_EMSIG_DIGESTONLY

```

The algorithm **RSA-PSS** is not available for this function. Use [`SIG_SignData`](#SIG_SignData) instead.

### Example (VBA core function)

```

Dim abData(3) As Byte
Dim abBlock() As Byte
Dim abCheck() As Byte
Dim nDataLen As Long
Dim nBlockLen As Long
Dim nLen As Long
Dim nRet As Long

' Our message data, 4 bytes long
abData(0) = &HDE
abData(1) = &HAD
abData(2) = &HBE
abData(3) = &HEF
nDataLen = 4
Debug.Print "DATA   =" & cnvHexStrFromBytes(abData)
' Set up output block with correct size
nBlockLen = 64
ReDim abBlock(nBlockLen - 1)
' Encode ready for encryption with default algorithm
nRet = RSA_EncodeMsg(abBlock(0), nBlockLen, abData(0), nDataLen, PKI_EME_PKCSV1_5)
If (nRet < 0) Then
	MsgBox "Encoding Error"
	Exit Function
End If
Debug.Print "BLOCK  =" & cnvHexStrFromBytes(abBlock)

' Now encrypt this block using RSA_RawPublic
' ...
' ... and send to recipient ...
' ...
' who decrypts using RSA_RawPrivate to get the encoded block

' Recover the message from the encoded block
' How long is it?
nLen = RSA_DecodeMsg(0, 0, abBlock(0), nBlockLen, PKI_EME_PKCSV1_5)
If (nLen < 0) Then
	MsgBox "Decryption Error"
	Exit Function
End If
ReDim abCheck(nLen - 1)
nLen = RSA_DecodeMsg(abCheck(0), nLen, abBlock(0), nBlockLen, PKI_EME_PKCSV1_5)
Debug.Print "DECODED=" & cnvHexStrFromBytes(abCheck)

 ' Alternative using more-secure OAEP algorithm
nRet = RSA_EncodeMsg(abBlock(0), nBlockLen, abData(0), nDataLen, PKI_EME_OAEP)
If (nRet < 0) Then
	MsgBox "Encoding Error"
	Exit Function
End If
Debug.Print "BLOCK  =" & cnvHexStrFromBytes(abBlock)
' ...
nLen = RSA_DecodeMsg(0, 0, abBlock(0), nBlockLen, PKI_EME_OAEP)
If (nLen < 0) Then
	MsgBox "Decryption Error"
	Exit Function
End If
ReDim abCheck(nLen - 1)
nLen = RSA_DecodeMsg(abCheck(0), nLen, abBlock(0), nBlockLen, PKI_EME_OAEP)
Debug.Print "DECODED=" & cnvHexStrFromBytes(abCheck)

```

More detailed examples are given in the section [Raw RSA Techniques](#rawrsa).

### Example (VBA wrapper function)

```

Dim lpData() As Byte
Dim lpBlock() As Byte
Dim lpDecoded() As Byte
Dim nBlockLen As Long
nBlockLen = 512 \ 8

lpData = cnvBytesFromHexStr("DEADBEEF")

lpBlock = rsaEncodeMsg(nBlockLen, lpData, PKI_EME_PKCSV1_5)
Debug.Print cnvHexStrFromBytes(lpBlock)
lpDecoded = rsaDecodeMsg(lpBlock, PKI_EME_PKCSV1_5)
Debug.Print "DECODED=" & cnvHexStrFromBytes(lpDecoded)

lpBlock = rsaEncodeMsg(nBlockLen, lpData, PKI_EME_OAEP)
Debug.Print cnvHexStrFromBytes(lpBlock)
lpDecoded = rsaDecodeMsg(lpBlock, PKI_EME_OAEP)
Debug.Print "DECODED=" & cnvHexStrFromBytes(lpDecoded)

lpBlock = rsaEncodeMsg(nBlockLen, lpData, PKI_EMSIG_PKCSV1_5 Or PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpBlock)
lpDecoded = rsaDecodeMsg(lpBlock, PKI_EMSIG_PKCSV1_5)
Debug.Print "DECODED=" & cnvHexStrFromBytes(lpDecoded)

Debug.Print "DIGEST =" & hashHexFromBytes(lpData, PKI_HASH_SHA256)

```

### See Also

[RSA_DecodeMsg](#RSA_DecodeMsg)
[RSA_RawPublic](#RSA_RawPublic)
[RSA_RawPrivate](#RSA_RawPrivate)
[Raw RSA Techniques](#rawrsa)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_Encrypt"></a>RSA_Encrypt
-----------------------------------

Encrypt a short message using RSA encryption.

### VBA/VB6 Syntax

`Public Declare Function RSA_Encrypt Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByRef lpInput As Byte, ByVal nInputLen As Long, ByVal strPublicKeyFile As String, ByVal strParameters As String, ByVal nOptions As Long) As Long`

`nRet = RSA_Encrypt(lpOutput(0), nOutBytes, lpInput(0), nInputLen, strPublicKeyFile, strParameters, nOptions)`

### C/C++ Syntax

`long __stdcall RSA_Encrypt(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpInput, long nInputLen, const char *szPublicKeyFile, const char *szParameters, long nOptions);`

### Parameters

*lpOutput*
:   [out] byte array to receive the encrypted output.

*nOutBytes*
:   [in] maximum length of the output array.

*lpInput*
:   [in] byte array containing the data to be encrypted.

*nInputLen*
:   [in] length of input in bytes.

*szPublicKeyFile*
:   [in] specifying the name of the public key file or X.509 certificate
	(or a string containing the key or certificate in [PEM format](#pemstring), or a valid internal public key string).

*szParameters*
:   [in] For specialist use. Specify `""`. See remarks.

*nOptions*
:   [in] option flags.
Include one of the following:-  

`PKI_EME_PKCSV1_5` (0) to encrypt using the RSAES-PKCS1-v1_5 encryption scheme (default).  

`PKI_EME_OAEP` to encrypt using the RSAES-OAEP encryption scheme.  

If you have selected `PKI_EME_OAEP`, then add one of these options to set the hash function for EME-OAEP encoding:  

`PKI_HASH_SHA1` (0) to use SHA-1 (default).  

`PKI_HASH_SHA224` to use SHA-224  

`PKI_HASH_SHA256` to use SHA-256  

`PKI_HASH_SHA384` to use SHA-384  

`PKI_HASH_SHA512` to use SHA-512  

and, optionally, add:-  

`PKI_MGF_MGF1SHA1` to force the MGF hash function to be SHA-1 (default = same as encoding hash function set above)

### Returns (VBA/C)

If successful, the return value is the number of bytes required to store the full output data. If an error occurs, it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`rsaEncrypt`](#VB_rsaEncrypt) (lpInput() As Byte, szPublicKeyFile As String, Optional nOptions As Long = 0, Optional szParameters As String = "") As Byte()

### .NET Equivalent

[Rsa.Encrypt Method](#M_Rsa_Encrypt)  

### C++ (STL) Equivalent

static bvec_t [dipki::Rsa::Encrypt](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a7a1985fcfbb3e85601fb5b45242669b6 "External link") (const bvec_t &data, const std::string &publicKeyFileOrString, EME method=EME::PKCSv1_5, HashAlg hashAlg=HashAlg::Sha1, AdvOpts advOpts=AdvOpts::Default, const std::string &params="")

### Python Equivalent

static [Rsa.encrypt](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.encrypt "External link")(data, pubkeyfileorstring, method=EME.PKCSV1_5, hashalg=HashAlg.SHA1, advopts=AdvOpts.DEFAULT, params="")

### Remarks

Set *nOutBytes* to zero and/or *lpOutput* to 0 (or `NULL`) to return the required number of bytes.
The output is *always* the same length in bytes as the RSA modulus, which can be found directly using the [RSA_KeyBytes()](#RSA_KeyBytes) function.

There is a limit on the length of data that can be encrypted. For RSAES-PKCS1-V1_5, *nInputLen* must not be greater than the key length in bytes (*k*) minus 11.
For RSAES-OAEP, *nInputLen* must not be greater than `k - 2*hLen - 2`, where *hLen* is the length in bytes of the hash function output.
Note this means, for example, that you cannot use SHA-512 with a 1024-bit RSA key with RSAES-OAEP.

The default parameters for RSA-OAEP encoding are 

```

hashAlgorithm = sha1,
maskGenAlgorithm = mgf1SHA1 (MGF1 with SHA-1)
pSourceAlgorithm =pSpecifiedEmpty (label L is the empty string)

```

You can change the hash algorithm using *nOptions* (and by default the MGF1 hash algorithm will be the same), and you can force the MGF1 hash algorithm to be SHA-1.
You cannot change the mask generation algorithm (there isn't another!) or the pSourceAlgorithm parameter (i.e. the label is always the empty string).
For more details see [RSA encryption and signature schemes](#rsaschemes).

To carry out tests against known test vectors, you can pass a fixed seed value in *szParameters*. For example, 
`"seed=18b776ea21069d69776a33e96bad48e1dda0a5ef"`. This string *must* begin with `"seed="` and be followed by the
seed value in hexadecimal encoding. This must represent a byte array of exactly *hLen* bytes, the length of the output of the hash function.

### Example (VBA core function)

```

Dim strPriKeyFile As String
Dim strPubKeyFile As String
Dim abMsg() As Byte
Dim nMsgLen As Long
Dim abEnc() As Byte
Dim nEncLen As Long
Dim abDec() As Byte
Dim nDecLen As Long
Dim strOkHex As String

' RSAES-OAEP Encryption Example 1.1 from `oaep-vect.txt` in `pkcs-1v2-1-vec.zip`
' RSA key file 1024-bit
strPubKeyFile = "rsa-oaep-1.pub"
strPriKeyFile = "rsa-oaep-1.p8"

' Message to be encrypted:
abMsg = cnvBytesFromHexStr("6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34")
nMsgLen = UBound(abMsg) + 1
Debug.Print "MSG=" & cnvHexStrFromBytes(abMsg)

' 1. Encrypt using RSA-OAEP but set seed to be a fixed value to compare with test vector
nEncLen = RSA_Encrypt(0, 0, abMsg(0), nMsgLen, strPubKeyFile, "seed=18b776ea21069d69776a33e96bad48e1dda0a5ef", PKI_EME_OAEP)
Debug.Print "RSA_Encrypt() returns " & nEncLen & " (expecting 128 = 1024 bits)"
' Allocate memory for byte array
ReDim abEnc(nEncLen - 1)
' Do the business - this should always give the same result
nEncLen = RSA_Encrypt(abEnc(0), nEncLen, abMsg(0), nMsgLen, strPubKeyFile, "seed=18b776ea21069d69776a33e96bad48e1dda0a5ef", PKI_EME_OAEP)
Debug.Print "ENC=" & cnvHexStrFromBytes(abEnc)

' Known answer from test vector
strOkHex = "354fe67b4a126d5d35fe36c777791a3f7ba13def484e2d3908aff722fad468fb21696de95d0be911c2d3174f8afcc201035f7b6d8e69402de5451618c21a535fa9d7bfc5b8dd9fc243f8cf927db31322d6e881eaa91a996170e657a05a266426d98c88003f8477c1227094a0d9fa1e8c4024309ce1ecccb5210035d47ac72e8a"
Debug.Print "OK =" & strOkHex

' 2. Decrypt - the private key is unencrypted with no password
nDecLen = RSA_Decrypt(0, 0, abEnc(0), nEncLen, strPriKeyFile, "", "", PKI_EME_OAEP)
Debug.Print "RSA_Decrypt() returns " & nDecLen
' Allocate memory for byte array
ReDim abDec(nDecLen - 1)
' Decrypt
nDecLen = RSA_Decrypt(abDec(0), nDecLen, abEnc(0), nEncLen, strPriKeyFile, "", "", PKI_EME_OAEP)
Debug.Print "DEC=" & cnvHexStrFromBytes(abDec)

' 3. Encrypt using RSA-OAEP using SHA-256
nEncLen = RSA_Encrypt(0, 0, abMsg(0), nMsgLen, strPubKeyFile, "", PKI_EME_OAEP + PKI_HASH_SHA256)
Debug.Print "RSA_Encrypt() returns " & nEncLen & " (expecting 128 = 1024 bits)"
' Allocate memory for byte array
ReDim abEnc(nEncLen - 1)
' Do the business - this will be different each time
nEncLen = RSA_Encrypt(abEnc(0), nEncLen, abMsg(0), nMsgLen, strPubKeyFile, "", PKI_EME_OAEP + PKI_HASH_SHA256)
Debug.Print "ENC=" & cnvHexStrFromBytes(abEnc)

' 4. Decrypt - we must specify the hash function used to encrypt
nDecLen = RSA_Decrypt(0, 0, abEnc(0), nEncLen, strPriKeyFile, "", "", PKI_EME_OAEP + PKI_HASH_SHA256)
Debug.Print "RSA_Decrypt() returns " & nDecLen
' Allocate memory for byte array
ReDim abDec(nDecLen - 1)
' Decrypt
nDecLen = RSA_Decrypt(abDec(0), nDecLen, abEnc(0), nEncLen, strPriKeyFile, "", "", PKI_EME_OAEP + PKI_HASH_SHA256)
Debug.Print "DEC=" & cnvHexStrFromBytes(abDec)

```

```

MSG=6628194E12073DB03BA94CDA9EF9532397D50DBA79B987004AFEFE34
RSA_Encrypt() returns 128 (expecting 128 = 1024 bits)
ENC=354FE67B4A126D5D35FE36C777791A3F7BA13DEF484E2D3908AFF722FAD468FB21696DE95D0BE911C2D3174F8AFCC201035F7B6D8E69402DE5451618C21A535FA9D7BFC5B8DD9FC243F8CF927DB31322D6E881EAA91A996170E657A05A266426D98C88003F8477C1227094A0D9FA1E8C4024309CE1ECCCB5210035D47AC72E8A
OK =354fe67b4a126d5d35fe36c777791a3f7ba13def484e2d3908aff722fad468fb21696de95d0be911c2d3174f8afcc201035f7b6d8e69402de5451618c21a535fa9d7bfc5b8dd9fc243f8cf927db31322d6e881eaa91a996170e657a05a266426d98c88003f8477c1227094a0d9fa1e8c4024309ce1ecccb5210035d47ac72e8a
RSA_Decrypt() returns 28
DEC=6628194E12073DB03BA94CDA9EF9532397D50DBA79B987004AFEFE34
RSA_Encrypt() returns 128 (expecting 128 = 1024 bits)
ENC=9BF3C801D9C73CD6FDDBF3C80715DD83A076D11BDCC1F73DC3ED7999EB2A4BB18296591E0B574374BC17CFF2EC290BD4730D70C9E1AEFA1D453F64A1C15A4C8ECA4E6CE9E1EF76B9253B6636426A8BC16B65A76BD280AB8DD5DF7607F5EF09D2BCC72CABD2E26608DD17FF80705861A79E11F50DDEA6083A567B4EEA40CAA2C5
RSA_Decrypt() returns 28
DEC=6628194E12073DB03BA94CDA9EF9532397D50DBA79B987004AFEFE34

```

### Example (VBA wrapper function)

```

Dim strPubKeyFile As String
Dim lpMsg() As Byte
Dim lpEnc() As Byte
Dim strPriKeyFile As String
Dim lpDec() As Byte

' Message to be encrypted:
lpMsg = cnvBytesFromHexStr("6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34")
Debug.Print "MSG=" & cnvHexStrFromBytes(lpMsg)

' Use RSA-OEAP with SHA-256
strPubKeyFile = "rsa-oaep-1.pub"
lpEnc = rsaEncrypt(lpMsg, strPubKeyFile, PKI_EME_OAEP + PKI_HASH_SHA256)
' NB different each time...
Debug.Print "ENC=" & cnvHexStrFromBytes(lpEnc)
strPriKeyFile = "rsa-oaep-1.p8"
lpDec = rsaDecrypt(lpEnc, strPriKeyFile, "", PKI_EME_OAEP + PKI_HASH_SHA256)
Debug.Print "DEC=" & cnvHexStrFromBytes(lpDec)

strPubKeyFile = "rsa-oaep-1.pub"
' Set seed to fixed value for debugging....
lpEnc = rsaEncrypt(lpMsg, strPubKeyFile, PKI_EME_OAEP, "seed=18b776ea21069d69776a33e96bad48e1dda0a5ef")
Debug.Print "ENC=" & cnvHexStrFromBytes(lpEnc)
Debug.Print "OK =354fe67b4a126d5d35fe36c777791a3f7ba13def484e2d3908aff722fad468fb" _
    & "21696de95d0be911c2d3174f8afcc201035f7b6d8e69402de5451618c21a535f" _
    & "a9d7bfc5b8dd9fc243f8cf927db31322d6e881eaa91a996170e657a05a266426" _
    & "d98c88003f8477c1227094a0d9fa1e8c4024309ce1ecccb5210035d47ac72e8a"
' Decrypt
strPriKeyFile = "rsa-oaep-1.p8"
lpDec = rsaDecrypt(lpEnc, strPriKeyFile, "", PKI_EME_OAEP)
Debug.Print "DEC=" & cnvHexStrFromBytes(lpDec)

```

### See Also

[RSA_Decrypt](#RSA_Decrypt)
[RSA_EncodeMsg](#RSA_EncodeMsg)
[RSA_RawPublic](#RSA_RawPublic)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_FromXMLString"></a>RSA_FromXMLString
-----------------------------------------------

Creates an RSA key string in internal format from an XML string.

### VBA/VB6 Syntax

`Public Declare Function RSA_FromXMLString Lib "diCrPKI.dll" 
    (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strXmlString As String, 
    ByVal nOptions As Long) As Long`

`nRet = RSA_FromXMLString(strOutput, nOutChars, 
    strXmlString, nOptions) As Long`

### C/C++ Syntax

`long __stdcall RSA_FromXMLString(char *szOutput, long nOutChars, const char *szXmlString, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive key data either public or private.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szXmlString*
:   [in] containing the RSA public or private key in XML format

*nOptions*
:   [in] option flags:  

`PKI_DEFAULT` (0) to include the private key, if present (default)  

`PKI_XML_EXCLPRIVATE` to exclude the private key even if present  

`PKI_XML_REQPRIVATE` to require the private key to exist in the XML input or fail

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`rsaFromXMLString`](#VB_rsaFromXMLString) (szXmlString As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Rsa.FromXMLString Method (String)](#M_Rsa_FromXMLString_String)  

[Rsa.FromXMLString Method (String, Rsa.XmlOptions)](#M_Rsa_FromXMLString_StringRsa_XmlOptions)  

[Rsa.FromXMLString Method (String, Boolean)](#M_Rsa_FromXMLString_StringBoolean)  

### C++ (STL) Equivalent

static std::string [dipki::Rsa::FromXMLString](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#abe9c8f1422fc92c7539cdaa7abe65717 "External link") (const std::string &xmlstr, XmlOptions opts=XmlOptions::None)

### Python Equivalent

static [Rsa.from_xmlstring](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.from_xmlstring "External link")(xmlstr, opts=0)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

A key string created with this function can be used in the other RSA functions in this toolkit
that require a key in "internal" format.
Use this function to import an RSA key from another application.

Only US-ASCII characters are supported. 
The XML data should be well formed and must contain either an 
`RSAKeyValue` or `RSAKeyPair` element according to
[[XMLDSIG](#XMLDSIG)] or [[XKMS2](#XKMS)].
The parser has been designed to be pretty forgiving but don't push it too far.

The first such valid element found in the string will be converted and other data will be ignored.
If the XML data only contains the public key elements, the resulting internal string will contain a public key
and can be used in the functions in this toolkit that require a public key string.
If the XML data contains all the private key elements, the internal string will contain a private key
unless the `PKI_XML_EXCLPRIVATE` option is used. 
To convert a private key, all components of the key pair must be present; namely,
the `<Modulus>`, `<Exponent>`, 
`<D>`, `<P>`, `<Q>`, `<DP>`, `<DQ>`, 
and `<InverseQ>` elements as specified in [[XKMS2](#XKMS)]. 
To allow compatibility with older versions of XKMS out there,
the deprecated elements `<QINV>`, `<PublicExponent>` 
and `<PrivateExponent>` will be accepted.

*[New in v20.0]*
Element names with a prefix, e.g. `<ds:Modulus>`, are now accepted.

To make life easier to import RSA key data that exists in hexadecimal format, the user can 
force the function to decode the data in hexadecimal format instead of base64 by adding an attribute
with the value `"hexBinary"` to each of the component elements of the RSAKeyValue. For example

```

<Exponent EncodingType="hexBinary">010001</Exponent>

```

The attribute name is not important.
This practice is not in conformance with any existing W3C standard (that we're aware of, anyway) but is included
for convenience where the user is creating the XML file by hand using hex data.

### Example (VBA core function)

This example converts an XML string into an internal public key that can be used in the other 
public key functions in this toolkit.

```

    Dim strInternalKey As String
    Dim strXML As String
    Dim nLen As Long
    Dim nRet As Long
    
    strXML = "<RSAKeyValue>" _
& "<Modulus>CmZ5HcaYgWjeerd0Gbt/sMABxicQJwB1FClC4ZqNjFH" _
& "QU7PjeCod5dxa9OvplGgXARSh3+Z83Jqa9V1lViC7qw==</Modulus>" _
& "<Exponent>AQAB</Exponent>" _
& "</RSAKeyValue>"

    nLen = RSA_FromXMLString("", 0, strXML, 0)
    If nLen <= 0 Then
        MsgBox ("Error: " & nLen)
        Exit Function
    End If
    strInternalKey = String(nLen, " ")
    nLen = RSA_FromXMLString(strInternalKey, Len(strInternalKey), strXML, 0)
    strInternalKey = Left(strInternalKey, nLen)
    
    Debug.Print "INTKEY=" & strInternalKey
    
    nRet = RSA_CheckKey(strInternalKey, 0)
    Debug.Print "RSA_CheckKey returns " & nRet

```

The second example is the same as the first except the XML data is in hexadecimal format.

```

    Dim strInternalKey As String
    Dim strXML As String
    Dim nLen As Long
    Dim nRet As Long
    
    strXML = "<RSAKeyValue>" _
    & "<Modulus EncodingType='hexBinary'>0A66791D" _
    & "C6988168DE7AB77419BB7FB0C001C627102700751429" _
    & "42E19A8D8C51D053B3E3782A1DE5DC5AF4EBE9946817" _
    & "0114A1DFE67CDC9A9AF55D655620BBAB</Modulus>" _
    & "<Exponent EncodingType='hexBinary'>010001</Exponent>" _
    & "</RSAKeyValue>"

    nLen = RSA_FromXMLString("", 0, strXML, 0)
    If nLen <= 0 Then
        MsgBox ("Error: " & nLen)
        Exit Function
    End If
    strInternalKey = String(nLen, " ")
    nLen = RSA_FromXMLString(strInternalKey, Len(strInternalKey), strXML, 0)
    strInternalKey = Left(strInternalKey, nLen)
    
    Debug.Print "INTKEY=" & strInternalKey
    
    nRet = RSA_CheckKey(strInternalKey, 0)
    Debug.Print "RSA_CheckKey returns " & nRet

```

Both examples should produce the output (shortened here):

```

INTKEY=MEcCQApmeR3...yamvVdZVYgu6sCAwEAAQ==
RSA_CheckKey returns 1

```

### Example (VBA wrapper function)

```

Dim strPrivateKey As String
strPrivateKey = rsaReadPrivateKey("AlicePrivRSASign.p8e", "password")
Debug.Print rsaToXMLString(strPrivateKey, 0)
Debug.Print rsaToXMLString(strPrivateKey, PKI_XML_EXCLPRIVATE Or PKI_XML_HEXBINARY)
Debug.Print rsaToXMLStringEx(strPrivateKey, "ds", PKI_XML_EXCLPRIVATE)
' Now derive internal private key string from XML
Dim strXML As String
Dim strKey As String
strXML = rsaToXMLString(strPrivateKey)
strKey = rsaFromXMLString(strXML)
Debug.Print "Key length = " & RSA_KeyBits(strKey) & " bits"
```

### See Also

[RSA_ToXMLString](#RSA_ToXMLString)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_GetPrivateKeyFromPFX"></a>RSA_GetPrivateKeyFromPFX
-------------------------------------------------------------

Extracts an encrypted private key from a PKCS-12 PKCS8ShroudedKeyBag, saving the output
directly as a new file.

### VBA/VB6 Syntax

`Public Declare Function RSA_GetPrivateKeyFromPFX Lib "diCrPKI.dll" 
    (ByVal strOutputFile As String, ByVal strPfxFile As String, 
    ByVal nOptions As Long) As Long`

`nRet = RSA_GetPrivateKeyFromPFX(strOutputFile, strPfxFile, 
   	nOptions) As Long`

### C/C++ Syntax

`long __stdcall RSA_GetPrivateKeyFromPFX(const char *szFileOut, const char *szPfxFile, long nOptions);`

### Parameters

*szFileOut*
:   [in] specifying the filename of the output file to be created.

*szPfxFile*
:   [in] containing the PFX filename

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful, it returns the number of bytes written to the output file;
otherwise it returns a negative [error code](#errorcodes).

### .NET Equivalent

[Rsa.GetPrivateKeyFromPFX Method](#M_Rsa_GetPrivateKeyFromPFX)  

### C++ (STL) Equivalent

static int [dipki::Rsa::GetPrivateKeyFromPFX](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a238dd633405d9a5174a6a1762db151e7 "External link") (const std::string &outputFile, const std::string &pfxFile)

### Python Equivalent

static [Rsa.get_privatekey_from_pfx](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.get_privatekey_from_pfx "External link")(outputfile, pfxfile)

### Remarks

The first `pkcs-12-pkcs-8ShroudedKeyBag` found in the PFX file will be extracted and saved directly
as a BER-encoded `EncryptedPrivateKeyInfo` file.
No decryption or other conversion is carried out.

### Example

```

nChars = RSA_GetPrivateKeyFromPFX(strEPKFile, strPfxFile, 0)

```

### See Also

[RSA_ReadEncPrivateKey](#RSA_ReadEncPrivateKey)
[RSA_ReadPrivateKeyFromPFX](#RSA_ReadPrivateKeyFromPFX)
[PFX_MakeFile](#PFX_MakeFile)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_GetPublicKeyFromCert"></a>RSA_GetPublicKeyFromCert
-------------------------------------------------------------

Reads a public key from an X.509 certificate into an "internal" public key string.

### VBA/VB6 Syntax

`Public Declare Function RSA_GetPublicKeyFromCert Lib "diCrPKI.dll" 
    (ByVal strPublicKey As String, ByVal nOutChars As Long, ByVal strCertFileName As String, 
    ByVal nOptions As Long) As Long`

`nRet = RSA_GetPublicKeyFromCert(strPublicKey, nOutChars, 
    strCertFileName, nOptions) As Long`

### C/C++ Syntax

`long __stdcall RSA_GetPublicKeyFromCert(char *szOutput, long nOutChars, const char *szCertFile, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive encoded public key data.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szCertFile*
:   [in] specifying the filename of an X.509 certificate file
	(or [base64 representation](#base64forcert)).

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a negative [error code](#errorcodes).

### .NET Equivalent

[Rsa.GetPublicKeyFromCert Method](#M_Rsa_GetPublicKeyFromCert)  

### Remarks

Call the function with an empty or NULL *szOutput* string or zero *nOutChars* parameter to find out the required length of
the output string. C/C++ users should add one to this value when allocating memory.
Both binary BER-encoded and PEM-style base64-encoded certificates can be read, 
or the certificate can be passed directly as a string in [base64 representation](#base64forcert).

*Woops!* The name of this function is an exception to our usual convention that 
"Read" means read-into-internal-string and "Get" means extract-and-save-as-a-file.
By rights this function should be called "RSA_**Read**PublicKeyFromCert". 
Sorry.

### Example

This code reads Alice's public key from her certificate and saves in a PKCS#1 public key file.
The certificate is from [[SMIME-EX]](#SMIME-EX).

```

Dim strCertFile As String
Dim strKeyFile As String
Dim strPublicKey As String
Dim nChars As Long
Dim nRet As Long

strCertFile = "AliceRSASignByCarl.cer"
' First find out the length of string we need
nChars = RSA_GetPublicKeyFromCert(vbNullString, 0, strCertFile, 0)
Debug.Print "RSA_GetPublicKeyFromCert returns " & nChars & " (expecting +ve)"
If nChars <= 0 Then
    Debug.Print "ERROR: " & pkiErrorLookup(nChars)
    Exit Sub
End If
' Pre-dimension the string to receive data - IMPORTANT
strPublicKey = String(nChars, " ")
' Read in the Public Key in our "internal" format
nRet = RSA_GetPublicKeyFromCert(strPublicKey, nChars, strCertFile, 0)
Debug.Print "Public key is " & RSA_KeyBits(strPublicKey) & " bits long"

' Now save as a PKCS#1 public key file
strKeyFile = "AlicePubRSA.pub"
nRet = RSA_SavePublicKey(strKeyFile, strPublicKey, 0)
Debug.Print "RSA_SavePublicKey returns " & nRet
If nRet = 0 Then
    Debug.Print "Saved as public key file '" & strKeyFile & "'"
Else
    Debug.Print "ERROR: " & pkiErrorLookup(nRet)
End If

```

This should result in the output:

```

RSA_GetPublicKeyFromCert returns 220 (expecting +ve)
Public key is 1024 bits long
RSA_SavePublicKey returns 0
Saved as public key file 'AlicePubRSA.pub'

```

### See Also

[RSA_SavePublicKey](#RSA_SavePublicKey)
[RSA_PublicKeyFromPrivate](#RSA_PublicKeyFromPrivate)
[X509_GetCertFromP7Chain](#X509_GetCertFromP7Chain)
[X509_GetCertFromPFX](#X509_GetCertFromPFX)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_KeyBits"></a>RSA_KeyBits
-----------------------------------

Returns the length of key in bits given the public or private key string.

### VBA/VB6 Syntax

`Public Declare Function RSA_KeyBits Lib "diCrPKI.dll" 
    (ByVal strKey As String) As Long`

`nRet = RSA_KeyBits(strKey)`

### C/C++ Syntax

`long __stdcall RSA_KeyBits(const char *szKeyString);`

### Parameters

*szKeyString*
:   [in] containing the RSA private or public key string.

### Returns (VBA/C)

returns the number of significant bits in the key modulus or a
negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`rsaKeyBits`](#VB_rsaKeyBits) (szKeyString As String) As Long

### .NET Equivalent

[Rsa.KeyBits Method](#M_Rsa_KeyBits_String) (String)  
[Rsa.KeyBits Method](#M_Rsa_KeyBits_StringBuilder) (StringBuilder)  

### C++ (STL) Equivalent

static int [dipki::Rsa::KeyBits](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a6f495276f394a1eb0764e67c7d710206 "External link") (const std::string &keyStr)

### Python Equivalent

static [Rsa.key_bits](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.key_bits "External link")(keystr)

### Remarks

### Example

### See Also

[RSA_KeyBytes](#RSA_KeyBytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_KeyBytes"></a>RSA_KeyBytes
-------------------------------------

Returns the length of key in complete bytes (octets) given the public or private key string.

### VBA/VB6 Syntax

`Public Declare Function RSA_KeyBytes Lib "diCrPKI.dll" 
    (ByVal strKey As String) As Long`

`nRet = RSA_KeyBytes(strKey)`

### C/C++ Syntax

`long __stdcall RSA_KeyBytes(const char *szKeyString);`

### Parameters

*szKeyString*
:   [in] containing the RSA private or public key string.

### Returns (VBA/C)

returns the number of complete bytes (8-bit octets) in the key modulus or a
negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`rsaKeyBytes`](#VB_rsaKeyBytes) (szKeyString As String) As Long

### .NET Equivalent

[Rsa.KeyBytes Method](#M_Rsa_KeyBytes_String) (String)  
[Rsa.KeyBytes Method](#M_Rsa_KeyBytes_StringBuilder) (StringBuilder)  

### C++ (STL) Equivalent

static int [dipki::Rsa::KeyBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a2f98ec43d53954c0eff33559b9ab07de "External link") (const std::string &keyStr)

### Python Equivalent

static [Rsa.key_bytes](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.key_bytes "External link")(keystr)

### Remarks

Use this function to find out the required length of the encryption block for "raw" RSA encryption.

### Example

### See Also

[RSA_KeyBits](#RSA_KeyBits)
[RSA_RawPublic](#RSA_RawPublic)
[RSA_RawPrivate](#RSA_RawPrivate)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_KeyHashCode"></a>RSA_KeyHashCode
-------------------------------------------

Computes the hash code of an "internal" RSA public or private key string.

### VBA/VB6 Syntax

`Public Declare Function RSA_KeyHashCode Lib "diCrPKI.dll" 
    (ByVal strKey As String) As Long`

`nRet = RSA_KeyHashCode(strKey)`

### C/C++ Syntax

`long __stdcall RSA_KeyHashCode(const char *szKeyString);`

### Parameters

*szKeyString*
:   [in] containing the RSA private or public key string in internal format.

### Returns (VBA/C)

A 32-bit hash code for the key, or zero on error.

### .NET Equivalent

[Rsa.KeyHashCode Method](#M_Rsa_KeyHashCode_String) (String)  

[Rsa.KeyHashCode Method](#M_Rsa_KeyHashCode_StringBuilder) (StringBuilder)  

### C++ (STL) Equivalent

static uint32_t [dipki::Rsa::KeyHashCode](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a2a29511d1ba843a5024f1f5e4fc1dc16 "External link") (const std::string &intKeyString)

### Python Equivalent

static [Rsa.key_hashcode](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.key_hashcode "External link")(keystr)

### Remarks

Use this function to compare internal key strings. As of version 3.0, internal key strings are encrypted
and cannot be compared directly. 
The actual string values may or may not be the same even though the underlying key is.
The hash code value will be the same for a given key. 
The hash code is computed to an internal algorithm and may return any integer value 
between -2,147,483,648 and 2,147,483,647.

If the key string is invalid, the return value is zero and a nonzero error code will be set (use [`PKI_ErrorCode`](#PKI_ErrorCode) to check).
There is a very small chance (one in 4 billion) that a valid key string returns a hash code of zero.

### Example

See the example in [`RSA_ReadPrivateKeyInfo`](#RSA_ReadPrivateKeyInfo).

### See Also

[RSA_KeyBits](#RSA_KeyBits)
[RSA_KeyBytes](#RSA_KeyBytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_KeyMatch"></a>RSA_KeyMatch
-------------------------------------

Verifies that a pair of "internal" RSA private and public key strings are matched.

### VBA/VB6 Syntax

`Public Declare Function RSA_KeyMatch Lib "diCrPKI.dll" 
    (ByVal strPrivateKey As String, ByVal strPublicKey As String) As Long`

`nRet = RSA_KeyMatch(strPrivateKey, strPublicKey)`

### C/C++ Syntax

`long __stdcall RSA_KeyMatch(const char *szPrivateKey, const char *szPublicKey);`

### Parameters

*szPrivateKey*
:   [in] containing an "internal" RSA private key string.

*szPublicKey*
:   [in] containing an "internal" RSA public key string.

### Returns (VBA/C)

If the pair of private and public keys match, the return value is zero (0); 
if the key strings are valid but not matched, the return value is NO_MATCH_ERROR (-21). 
If an error occurs, it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

[Rsa.KeyMatch Method](#M_Rsa_KeyMatch_StringString) (String)  
[Rsa.KeyMatch Method](#M_Rsa_KeyMatch_StringBuilderStringBuilder) (StringBuilder)  

### C++ (STL) Equivalent

static bool [dipki::Rsa::KeyMatch](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a50c94da4020db9255ef92080d6d4fe52 "External link") (const std::string &priKeyStr, const std::string &pubKeyStr)

### Python Equivalent

static [Rsa.key_match](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.key_match "External link")(prikeystr, pubkeystr)

### Remarks

This function allows you to check that a private key file is matched with the public key in an X.509 certificate.
You must read the keys into "internal" key strings before comparing.
Note that the return value for success is zero.

### Example

```

Dim strCertFile As String
Dim strKeyFile As String
Dim strPassword As String
Dim strPublicKey As String
Dim strPrivateKey As String
Dim nRet As Long

' Input files
strCertFile = "AAA010101AAAsd.cer"
strKeyFile = "AAA010101AAA_0408021316S.key"
' Test password - CAUTION: DO NOT hardcode production passwords!
strPassword = "Empresa1"

' Read in private key from encrypted .key file
strPrivateKey = rsaReadPrivateKey(strKeyFile, strPassword)
If Len(strPrivateKey) > 0 Then
    Debug.Print "Private key is " & RSA_KeyBits(strPrivateKey) & " bits"
Else
    Debug.Print "ERROR: Cannot read private key file."
    Exit Sub
End If

' Clean up password as we are done with it
strPassword = wipeString(strPassword)

' Read in public key from certificate
strPublicKey = rsaGetPublicKeyFromCert(strCertFile)
If Len(strPublicKey) > 0 Then
    Debug.Print "Public key is " & RSA_KeyBits(strPublicKey) & " bits"
Else
    Debug.Print "ERROR: Cannot read certificate file."
    Exit Sub
End If

' See if the two key strings match
nRet = RSA_KeyMatch(strPrivateKey, strPublicKey)
If nRet = 0 Then
    Debug.Print "OK, key strings match."
Else
    Debug.Print "FAILED: key strings do not match."
End If

' Clean up private key string
strPrivateKey = wipeString(strPrivateKey)

```

Using the sample Mexican Government SAT files, the output is as follows:

```

Private key is 1024 bits
Public key is 1024 bits
OK, key strings match.

```

### See Also

[RSA_KeyHashCode](#RSA_KeyHashCode)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_KeyValue"></a>RSA_KeyValue
-------------------------------------

Extracts a base64-encoded RSA key value from internal key string.

### VBA/VB6 Syntax

`Public Declare Function RSA_KeyValue Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strKeyString As String, ByVal strFieldName As String, ByVal nOptions As Long) As Long`

`nRet = RSA_KeyValue(strOutput, nOutChars, strKeyString, strFieldName, nOptions)`

### C/C++ Syntax

`long __stdcall RSA_KeyValue(char *szOutput, long nOutChars, const char *szKeyString, const char *szFieldName, long nOptions);`

### Parameters

*szOutput*
:   [out] string of sufficient length to receive the output

*nOutChars*
:   [in] specifying the maximum number of characters to be received

*szKeyString*
:   [in] Public or private key in internal string format

*szFieldName*
:   [in] Name of field to be extracted: `"Modulus"` or `"Exponent"`

*nOptions*
:   [in] option flags. Set to zero.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string; 
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`rsaKeyValue`](#VB_rsaKeyValue) (szKeyString As String, szFieldName As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Rsa.KeyValue Method](#M_Rsa_KeyValue)  

### C++ (STL) Equivalent

static std::string [dipki::Rsa::KeyValue](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a128b7ef2bae278e6b0856439e43d2e8d "External link") (const std::string &keyStr, const std::string &fieldName)

### Python Equivalent

static [Rsa.key_value](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.key_value "External link")(keystr, fieldname)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The output is a continuous string of base64 characters 
suitable for a `<RSAKeyValue>` node in an XML-DSIG document.

A typical `<RSAKeyValue>` node looks like this:

```

<RSAKeyValue>
  <Modulus>
    4IlzOY3Y9fXoh3Y5f06wBbtTg94Pt6vcfcd1KQ0FLm0S36aGJtTSb6pYKfyX7PqCUQ8wgL6xUJ5GRPEsu9gyz8
    ZobwfZsGCsvu40CWoT9fcFBZPfXro1Vtlh/xl/yYHm+Gzqh0Bw76xtLHSfLfpVOrmZdwKmSFKMTvNXOFd0V18=
  </Modulus>
  <Exponent>AQAB</Exponent>
</RSAKeyValue>

```

Use this function to populate the fields `<Modulus>` and `<Exponent>` for a given RSA key,
or to use the values in other computations.

### Example (VBA core function)

```

Dim nChars As Long
Dim strKeyString As String
Dim strFieldName As String
Dim strValue As String

' Read in key to internal string
strKeyString = rsaReadPublicKey("AliceRSASignByCarl.cer")

strFieldName = "Modulus"
nChars = RSA_KeyValue("", 0, strKeyString, strFieldName, 0)
If (nChars < 0) Then
    Debug.Print "ERROR: " & pkiErrorLookup(nChars)
    Exit Sub
End If
' Dimension output
strValue = String(nChars, " ")
nChars = RSA_KeyValue(strValue, nChars, strKeyString, strFieldName, 0)
Debug.Print strFieldName & "=" & strValue

strFieldName = "Exponent"
nChars = RSA_KeyValue("", 0, strKeyString, strFieldName, 0)
If (nChars < 0) Then
    Debug.Print "ERROR: " & pkiErrorLookup(nChars)
    Exit Sub
End If
' Dimension output
strValue = String(nChars, " ")
nChars = RSA_KeyValue(strValue, nChars, strKeyString, strFieldName, 0)
Debug.Print strFieldName & "=" & strValue

```

```

Modulus=4IlzOY3Y9fXoh3Y5f06wBbt ... +Gzqh0Bw76xtLHSfLfpVOrmZdwKmSFKMTvNXOFd0V18=
Exponent=AQAB

```

### Example (VBA wrapper function)

```

Dim strKeyString As String
Dim strFieldName As String
Dim strValue As String

strKeyString = rsaReadPublicKey("AliceRSASignByCarl.cer")
strFieldName = "Modulus"
strValue = rsaKeyValue(strKeyString, strFieldName)
Debug.Print strFieldName & "=" & strValue
strFieldName = "Exponent"
strValue = rsaKeyValue(strKeyString, strFieldName)
Debug.Print strFieldName & "=" & strValue
```

### See Also

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_MakeKeys"></a>RSA_MakeKeys
-------------------------------------

Generate an RSA key pair and save as two key files.  
*[Superseded by* `[RSA_MakeKeysXtd](#RSA_MakeKeysXtd)`.]

### VBA/VB6 Syntax

`Public Declare Function RSA_MakeKeys Lib "diCrPKI.dll" 
    (ByVal strPubKeyFile As String, ByVal strPvkKeyFile As String, 
    ByVal nBits As Long, ByVal nExpFermat As Long, ByVal nTests As Long, 
    ByVal nCount As Long, 
    ByVal strPassword As String, 
    ByVal strSeed As String, ByVal nSeedLen As Long,
    ByVal nOptionFlags As Long) As Long`

`nRet = RSA_MakeKeys(strPublicKeyFile, strPrivateKeyFile, nBits, nExpFermat,
         nTests, nCount, strPassword, 
         strSeed, nSeedLen, nOptionFlags)`

### C/C++ Syntax

`long __stdcall RSA_MakeKeys(const char *szPubKeyFile, const char *szEpkFile, long nBits, long nExpFermat, long nTests, long nCount, const char *szPassword, const void *lpSeed, long nSeedLen, long nOptions);`

### Parameters

*szPubKeyFile*
:   [in] name of public key file to be created.

*szEpkFile*
:   [in] name of encrypted private key file to be created.

*nBits*
:   [in] required key size in bits (minimum 96).

*nExpFermat*
:   [in] exponent *e* to be used. Select from:  

`PKI_RSAEXP_EQ_3` for 3  

`PKI_RSAEXP_EQ_5` for 5  

`PKI_RSAEXP_EQ_17` for 17 (0x11)  

`PKI_RSAEXP_EQ_257` for 257 (0x101)  

`PKI_RSAEXP_EQ_65537` for 65537 (0x10001) (default)

*nTests*
:   [in] specifying the number of Rabin-Miller tests to be performed 
(recommended at least 50).

*nCount*
:   [in] specifying the iteration count to be used when encrypting the private key
(default = 1; recommended at least 1000).

*szPassword*
:   [in] password to be used to encrypt the private key file.

*lpSeed*
:   [in] an (optional) user-specified seed to be used by the random number
generator (specify "" or NULL to ignore).

*nSeedLen*
:   [in] length of the seed in bytes.

*nOptions*
:   [in] a flag to indicate the algorithm to be used 
to encrypt the private key file. Select from:  

`PKI_PBE_SHA_3DES` (0) for `"pbeWithSHAAnd3-KeyTripleDES-CBC"` (default)  

or `PKI_PBE_PBES2` for `"pkcs5PBES2"` plus one of  

* `PKI_BC_DESEDE3` to use `des-EDE3-CBC` (default)
* `PKI_BC_AES128` to use `AES128-CBC`
* `PKI_BC_AES192` to use `AES192-CBC`
* `PKI_BC_AES256` to use `AES256-CBC`

(there are more options - see [security options for encrypted private keys](#encryptedkeyoptions))  

and optionally add  

`PKI_KEYGEN_INDICATE` to indicate progress in a console window (see remarks below),  

plus one of 

`PKI_KEY_FORMAT_PEM` to save the key files in PEM form (default is binary BER-encoded format) 

*or*
`PKI_KEY_FORMAT_SSL` to save the key files in PEM form with the public key as an OpenSSL-compatible subjectPublicKeyInfo file.

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`rsaMakeKeys`](#VB_rsaMakeKeys) (szPubKeyFile As String, szPriKeyFile As String, szPassword As String, nBits As Long, Optional nExpFermat As Long = PKI_RSAEXP_EQ_65537, Optional szParams As String = "", Optional nOptions As Long = 0) As Long

### .NET Equivalent

[Rsa.MakeKeys Method](#M_Rsa_MakeKeys_StringStringInt32Rsa_PublicExponentInt32StringRsa_PbeOptionsBooleanByte) (String, String, Int32, Rsa.PublicExponent, Int32, String, Rsa.PbeOptions, Boolean, Byte[])  

[Rsa.MakeKeys Method](#M_Rsa_MakeKeys_StringStringInt32Rsa_PublicExponentInt32StringCipherAlgorithmHashAlgorithmRsa_FormatBoolean) (String, String, Int32, Rsa.PublicExponent, Int32, String, CipherAlgorithm, HashAlgorithm, Rsa.Format, Boolean)  

### C++ (STL) Equivalent

static int [dipki::Rsa::MakeKeys](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a48dfe8237977369f90405443169a1bce "External link") (const std::string &publicKeyFile, const std::string &privateKeyFile, const std::string &password, int nbits, PublicExponent exponent=PublicExponent::Exp_EQ_65537, PbeScheme pbes=PbeScheme::Default, const std::string &paramString="", Format fileFormat=Format::Binary, bool showProgress=false)

### Remarks

The RSA key is stored by default as a pair of DER-encoded binary files. 
The public and private keys are encoded into ASN.1 values of type 
`RSAPublicKey` and `RSAPrivateKey` respectively (defined in PKCS #1).
The private key is then encrypted and encoded into a PKCS #8 `EncryptedPrivateKeyInfo` type.
Any existing files of the same names will be overwritten without warning.
The key length must be greater than 96 bits. The value of the exponent is limited to the five values listed.
The password and iteration count are used to encrypt the private key according to the 
specified PBE algorithm specified in *nOptionFlags*. 
The password should be a string of ASCII characters and must not contain any NUL characters (i.e. `Chr(0)`).
The seed is optional and is used to supplement the seeding of the random number generator.
The user may use the seed to provide some additional value ("user-supplied entropy") that is unique when the
keys are being generated. 
See [Random Number Generator and Seeds](#rnginfo) for more information.

The default format for the files is binary DER-encoded format. 
Use either the `PKI_KEY_FORMAT_PEM` *or* the `PKI_KEY_FORMAT_SSL` flag to save in
base64 "PEM" format. Files saved with the `PKI_KEY_FORMAT_SSL` flag should be compatible
with OpenSSL. For more details on the formats, see 
`[RSA_SavePublicKey()](#RSA_SavePublicKey)` 
and `[RSA_SaveEncPrivateKey()](#RSA_SaveEncPrivateKey)`.

Generating RSA key pairs can take some time. On a 1GHz P3 test machine, the following times were typical:

| Key size | Time |
| --- | --- |
| 512 | < 1 second |
| 1024 | 5 seconds |
| 2048 | 1 minute |
| 4096 | 6 minutes |
| 8192 | 1 hour |

Some programs like Office Access will get bored waiting for the longer processes to finish and may hang. 
Setting the `PKI_KEYGEN_INDICATE` flag will show progress in a separate console window (actually two, one for
p and one for q). Having a console window show progress will keep the parent application happy. 
A dot "." indicates a new candidate is being tested, 
and an asterisk "*" indicates that a Rabin-Miller test has been carried
out (that is the expensive part of the process). The program will close these console windows down automatically.
Do not use the `PKI_KEYGEN_INDICATE` option in a multi-threaded environment. 
For console-based programs, this option just shows the progress in the standard output. 

**Caution:** pressing Ctrl-C or Ctrl-Break in the console window will kill your entire process altogether;
that is, abort your whole application, which may not be what you want.

There is a very, very small possibility that the generator may fail to find a suitable prime number candidate
within the number of iterations it carries out. If this happens (we've never seen it, but it could in theory), the function
will return a `KEYGEN_FAILED_ERROR` error code 24. This in itself does not indicate a
systemic problem with the Toolkit, just an incredibly unlucky event. Let us know if it happens more than once.

### Example

```

Dim nRet As Long
Dim sPublicKeyFile As String
Dim sPrivateKeyFile As String
Dim sPassword As String
sPublicKeyFile = "mykey.pub"
sPrivateKeyFile = "mykey.p8e"
sPassword = "password"
' Create a new pair of RSA keys saved as BER-encoded files
Debug.Print "About to create a new RSA key pair..."
nRet = RSA_MakeKeys(sPublicKeyFile, sPrivateKeyFile, 512, _
    PKI_RSAEXP_EQ_3, 50, 1000, sPassword, "", 0, 0)  
Debug.Print "RSA_MakeKeys returns " & nRet & " (expected 0)"

```

The example above will generate a 512-bit RSA key pair and store in two files, a public key file `mykey.pub` 
and an encrypted private key file `mykey.p8e`. The exponent will be 3. 
Rabin-Miller tests will be carried out 50 times to verify that the values of p and q are prime.
The private key will be encrypted using the default `"pbeWithSHAAnd3-KeyTripleDES-CBC"` algorithm using the password
"password" and an iteration count of 1000.

```

strSeed = "yyyseed345"
nRet = RSA_MakeKeys(sPublicKeyFile, sPrivateKeyFile, 2048, 
    PKI_RSAEXP_EQ_65537, 64, 3000, "94tMhvTr7gvVy48q", strSeed, Len(strSeed), 
    PKI_PBE_PBKDF2_AES128)

```

The second example generates a 2048-bit RSA key pair with the exponent 65537 (0x10001). Sixty-four Rabin-Miller tests 
are used to test for primality. 
The private key will be encrypted using the PBES2 algorithm with AES-128 as the encryption scheme,
the password "94tMhvTr7gvVy48q", and
an iteration count of 3000. The string "yyyseed345" will be added to the RNG seeding process.
Note the use of `PKI_PBE_PBKDF2_AES128` as a replacement for the older (but still valid) option
`PKI_PBE_PBES2+PKI_BC_AES128`.

### See Also

[RSA_ReadEncPrivateKey](#RSA_ReadEncPrivateKey)
[RSA_ReadPublicKey](#RSA_ReadPublicKey)
[RSA_SaveEncPrivateKey](#RSA_SaveEncPrivateKey)
[RSA_SavePublicKey](#RSA_SavePublicKey)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_MakeKeysXtd"></a>RSA_MakeKeysXtd
-------------------------------------------

Generate an RSA key pair and save as two key files.

### VBA/VB6 Syntax

`Public Declare Function RSA_MakeKeysXtd Lib "diCrPKI.dll" (ByVal strPubKeyFile As String, ByVal strPriKeyFile As String, ByVal strPassword As String, ByVal nBits As Long, ByVal nExpFermat As Long, ByVal strParams As String, ByVal nOptions As Long) As Long`

`nRet = RSA_MakeKeysXtd(strPubKeyFile, strPriKeyFile, strPassword, nBits, nExpFermat, strParams, nOptionFlags)`

### C/C++ Syntax

`long __stdcall RSA_MakeKeysXtd(const char *szPubKeyFile, const char *szPriKeyFile, const char *szPassword, long nBits, long nExpFermat, const char *szParams, long nOptions);`

### Parameters

*szPubKeyFile*
:   [in] Output filename for public key.

*szPriKeyFile*
:   [in] Output filename for (encrypted) private key.

*szPassword*
:   [in] Password for encrypted private key (required).

*nBits*
:   [in] Required key modulus size in bits (minimum 96).

*nExpFermat*
:   [in] exponent *e* to be used. Select from:  

`PKI_RSAEXP_EQ_3` for 3  

`PKI_RSAEXP_EQ_5` for 5  

`PKI_RSAEXP_EQ_17` for 17 (0x11)  

`PKI_RSAEXP_EQ_257` for 257 (0x101)  

`PKI_RSAEXP_EQ_65537` for 65537 (0x10001) (default)

*szParams*
:   [in] Optional parameters. Set as the empty string `""` for defaults.
	Otherwise include a set of attribute-value pairs separated by a semi-colon ";" to set options from the following
* `count=<nnn>` to set the iteration count in the encrypted private key used in the PBKDF method,
	e.g. `"count=5000;"` [default=`2048`]
* `prf=<hmac-name>` to change the HMAC algorithm used in the PBKDF2 method,
	e.g. `"prf=hmacWithSHA256;"` [default=`hmacwithSHA1`]
* `rngseed=<string>` to add some extra user-specified additional seed for the random number generator,
	e.g. `"rngseed=pqrrr1234xyz;"`

Valid values for hmac-name are `{hmacWithSHA1|hmacWithSHA224|hmacWithSHA256|hmacWithSHA384|hmacWithSHA512}`.

*nOptions*
:   [in] a flag to indicate the password-based encryption scheme to be used to encrypt the private key file. 
Select from:  

`PKI_PBE_SHA_3DES` (0) for `"pbeWithSHAAnd3-KeyTripleDES-CBC"` from PKCS12 (default)  

`PKI_PBE_PBKDF2_DESEDE3` for PBKDF2 using `des-EDE3-CBC`  

`PKI_PBE_PBKDF2_AES128` for PBKDF2 using `aes128-CBC`  

`PKI_PBE_PBKDF2_AES192` for PBKDF2 using `aes192-CBC`  

`PKI_PBE_PBKDF2_AES256` for PBKDF2 using `aes256-CBC`  

(there are more options - see [security options for encrypted private keys](#encryptedkeyoptions))  

and optionally add  

`PKI_KEYGEN_INDICATE` to indicate progress in a console window (see remarks below),  

plus one of 

`PKI_KEY_FORMAT_PEM` to save the key files in PEM form (default is binary DER-encoded format) 

*or*
`PKI_KEY_FORMAT_SSL` to save the key files in PEM form with the public key as an OpenSSL-compatible subjectPublicKeyInfo file.

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

[Rsa.MakeKeys Method](#M_Rsa_MakeKeys_StringStringStringInt32Rsa_PublicExponentRsa_PbeOptionsStringRsa_FormatBoolean)  

### Python Equivalent

static [Rsa.make_keys](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.make_keys "External link")(pubkeyfile, prikeyfile, nbits, exponent, password, pbes=0, params='', fileformat=0)

### Remarks

The RSA keys are stored by default as a pair of DER-encoded binary files. 

Setting the `PKI_KEYGEN_INDICATE` flag will show progress in a separate console window (actually two, one for p and one for q). 
Having a console window show progress will keep a parent application (like MS Access) happy and prevent it hanging due to boredom. 
The program will close these console windows down automatically (do not use Ctrl-C or Ctrl-Break: it will kill your entire process altogether!).
Do not use the `PKI_KEYGEN_INDICATE` option in a multi-threaded environment. 
For console-based programs, this option just shows the progress in the standard output. 

### Example (VBA core function)

```

```

### Example (VBA wrapper function)

```

Dim r As Long
' Create a 2048-bit RSA key pair using defaults
r = rsaMakeKeys("myrsa2048.pub", "myrsa2048.p8e", "password", 2048)
' Same but using stronger security and in PEM format
r = rsaMakeKeys("myrsa2048ex.pub", "myrsa2048ex.p8e", "password1", 2048,,"count=6000;prf=hmacWithSHA256", PKI_PBE_PBKDF2_AES128 Or PKI_KEY_FORMAT_PEM)

```

### See Also

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_PublicKeyFromPrivate"></a>RSA_PublicKeyFromPrivate
-------------------------------------------------------------

Converts an internal RSA private key string into an internal public key string.

### VBA/VB6 Syntax

`Public Declare Function RSA_PublicKeyFromPrivate Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strKeyString As String, ByVal nOptions As Long) As Long`

`nRet = RSA_PublicKeyFromPrivate(strOutput, nOutChars, 
    strKeyString, nOptions) As Long`

### C/C++ Syntax

`long __stdcall RSA_PublicKeyFromPrivate(char *szOutput, long nOutChars, const char *szKeyString, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive public key data in encoded "internal" format.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szKeyString*
:   [in] containing a private key in "internal" format.

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`rsaPublicKeyFromPrivate`](#VB_rsaPublicKeyFromPrivate) (szKeyString As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Rsa.PublicKeyFromPrivate Method](#M_Rsa_PublicKeyFromPrivate)  

### C++ (STL) Equivalent

static std::string [dipki::Rsa::PublicKeyFromPrivate](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a32a2360cf76e4930b1a55950afdc6da4 "External link") (const std::string &keyStr)

### Python Equivalent

static [Rsa.publickey_from_private](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.publickey_from_private "External link")(intkeystr)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

Use this function if you need a public key string but only have the corresponding private key file.
The format used to store RSA private keys contains both the public and private components
(that is, *n* and *e* are present in both) 
so we can obtain the public key from its corresponding private key.

Note that internal key strings are only valid for the current session.

### Example (VBA core function)

This example reads in a private key to an internal private key string, displays some information about the key,
	then converts it to a public key string and displays its properties.

```

Dim strPriKeyFile As String
Dim strPrivateKey As String
Dim strPublicKey As String
Dim nChars As Long
Dim nCode As Long
Dim nRet As Long

' Read private key from encrypted private key file into internal string form
strPriKeyFile = "BobPrivRSAEncrypt.p8e"
strPrivateKey = rsaReadPrivateKey(strPriKeyFile, "password")
If Len(strPrivateKey) = 0 Then Exit Sub     'Catch error here
' Display some info about it
Debug.Print "Private key length = " & RSA_KeyBits(strPrivateKey) & " bits"
nCode = RSA_KeyHashCode(strPrivateKey)
Debug.Print "KeyHashCode=" & Hex(nCode)
nRet = RSA_CheckKey(strPrivateKey, 0)
Debug.Print "RSA_CheckKey returns " & nRet & ": (PKI_VALID_PRIVATEKEY=" & PKI_VALID_PRIVATEKEY & ")"

' Convert to public key string
nChars = RSA_PublicKeyFromPrivate("", 0, strPrivateKey, 0)
If nChars <= 0 Then Exit Sub    ' Catch error here
strPublicKey = String(nChars, " ")
nChars = RSA_PublicKeyFromPrivate(strPublicKey, Len(strPublicKey), strPrivateKey, 0)
 ' Display some info about it
Debug.Print "Public key length = " & RSA_KeyBits(strPublicKey) & " bits"
nCode = RSA_KeyHashCode(strPublicKey)
Debug.Print "KeyHashCode=" & Hex(nCode)
nRet = RSA_CheckKey(strPublicKey, 0)
Debug.Print "RSA_CheckKey returns " & nRet & ": (PKI_VALID_PUBLICKEY=" & PKI_VALID_PUBLICKEY & ")"

' Clean up
strPrivateKey = wipeString(strPrivateKey)

```

Note that the KeyHashCodes and bit lengths are the same.

```

Private key length = 1024 bits
KeyHashCode=6BCC120C
RSA_CheckKey returns 0: (PKI_VALID_PRIVATEKEY=0)
Public key length = 1024 bits
KeyHashCode=6BCC120C
RSA_CheckKey returns 1: (PKI_VALID_PUBLICKEY=1)

```

### Example (VBA wrapper function)

```

Dim strPrivateKey As String
Dim strPublicKey As String
' Read in private key to internal string
strPrivateKey = rsaReadPrivateKey("BobPrivRSAEncrypt.p8e", "password")
Debug.Assert Len(strPrivateKey) > 0
Debug.Print "Private key length = " & RSA_KeyBits(strPrivateKey) & " bits"
Debug.Print "KeyHashCode=0x" & Hex(RSA_KeyHashCode(strPrivateKey))
' Convert to public key string
strPublicKey = rsaPublicKeyFromPrivate(strPrivateKey)
Debug.Print "Public key length = " & RSA_KeyBits(strPublicKey) & " bits"
Debug.Print "KeyHashCode=0x" & Hex(RSA_KeyHashCode(strPublicKey))
```

### See Also

[RSA_SavePublicKey](#RSA_SavePublicKey)
[RSA_ReadEncPrivateKey](#RSA_ReadEncPrivateKey)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_RawPrivate"></a>RSA_RawPrivate
-----------------------------------------

Transforms (that is, encrypts or decrypts) raw data using an RSA private key.

### VBA/VB6 Syntax

`Public Declare Function RSA_RawPrivate Lib "diCrPKI.dll" 
    (ByRef lpData As Byte, ByVal nDataLen As Long, 
    ByVal strPrivateKey As String, ByVal nOptions As Long) As Long`

`nRet = RSA_RawPrivate(lpData(0), nDataLen, strPrivateKey, nOptions)`

### C/C++ Syntax

`long __stdcall RSA_RawPrivate(unsigned char *lpData, long nDataLen, const char *szPrivateKey, long nOptions);`

### Parameters

*lpData*
:   [in,out] array containing the data to be transformed.

*nDataLen*
:   [in] specifying the number of bytes of data.

*szPrivateKey*
:   [in] containing the RSA private key string.

*nOptions*
:   [in] option flags. Set to zero.

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`rsaRawPrivate`](#VB_rsaRawPrivate) (lpData() As Byte, szPrivateKey As String, Optional nOptions As Long = 0) As Byte()

### .NET Equivalent

[Rsa.RawPrivate Method](#M_Rsa_RawPrivate_ByteString) (Byte[], String)  
[Rsa.RawPrivate Method](#M_Rsa_RawPrivate_ByteStringInt32) (Byte[], String, Int32)  

### C++ (STL) Equivalent

static bvec_t [dipki::Rsa::RawPrivate](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a50a88a4e9650c3e384e25135eb8e6dd5 "External link") (const bvec_t &data, const std::string &keyStr)

### Python Equivalent

static [Rsa.raw_private](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.raw_private "External link")(block, prikeystr)

### Remarks

The data must be the same length as the RSA key modulus (use `RSA_KeyBytes()` to find out this).
The output is written over the input. The RSA private key must be provided in the internal key string format.

### Example (VBA core function)

This is adapted from  "Some Examples of the PKCS Standards: An RSA Laboratories Technical Note",
Burton S. Kaliski Jr., 1993 [[PKCS-EX](#PKCS-EX)].
It carries out the signing of the encryption block from section 3.2 using the 508-bit private key and then
verifies the signature using the corresponding public key. 
The keys are stored in files `rsa508.pub` and `rsa508.p8e`.

```

Dim strEPKFile As String
Dim strPubFile As String
Dim strPassword As String
Dim strPublicKey As String
Dim strPrivateKey As String
Dim nRet As Long
Dim strOutputFile As String
Dim abData() As Byte
Dim nDataLen As Long
Dim sHexData As String

strEPKFile = "rsa508.p8e"
strPassword = "password"

' Read in the deciphered private key string
strPrivateKey = rsaReadPrivateKey(strEPKFile, strPassword)
If Len(strPrivateKey) = 0 Then
    MsgBox "Unable to retrieve private key"
    Exit Function
End If
Debug.Print strPrivateKey

' Create some raw data to be RSA'd
' Ref: 3.2 Signing the CertificationRequestInfo encoding
' 64-octet EB in full:
'00 01 ff ff ff ff ff ff ff ff ff ff ff ff ff ff
'ff ff ff ff ff ff ff ff ff ff ff ff ff 00 30 20
'30 0c 06 08 2a 86 48 86 f7 0d 02 02 05 00 04 10
'dc a9 ec f1 c1 5c 1b d2 66 af f9 c8 79 93 65 cd

sHexData = "0001ffffffffffffffffffffffffffff" & _
    "ffffffffffffffffffffffffff003020" & _
    "300c06082a864886f70d020205000410" & _
    "dca9ecf1c15c1bd266aff9c8799365cd"

abData = cnvBytesFromHexStr(sHexData)
nDataLen = UBound(abData) - LBound(abData) + 1
Debug.Print "Input:  " & cnvHexStrFromBytes(abData)

' Now we have our data in a byte array and 
' our private key in string format,
' we are ready to do a "raw" operation
nRet = RSA_RawPrivate(abData(0), nDataLen, strPrivateKey, 0)
Debug.Print "RSA_RawPrivate returns " & nRet
If nRet <> 0 Then
    Debug.Print pkiGetLastError()
Else
    ' Display our results in hex format
    Debug.Print "Output: " & cnvHexStrFromBytes(abData)
End If

' Get the corresponding Public Key, also in a file
strPubFile = "rsa508.pub"
strPublicKey = rsaReadPublicKey(strPubFile)
Debug.Print strPublicKey

' Do a "raw" encryption with the public key
nRet = RSA_RawPublic(abData(0), nDataLen, strPublicKey, 0)
Debug.Print "RSA_RawPublic returns " & nRet
If nRet <> 0 Then
    Debug.Print pkiGetLastError()
Else
    ' Display our results in hex format
    Debug.Print "Decrypt:" & cnvHexStrFromBytes(abData)
End If

```

### Example (VBA wrapper function)

```

Dim strPrivateKey As String
Dim pt() As Byte
Dim ct() As Byte
strPrivateKey = rsaReadPrivateKey("rsa508.p8e", "password")
Debug.Assert Len(strPrivateKey) > 0
pt = cnvBytesFromHexStr("0001ffffffffffffffffffffffffffff" & _
    "ffffffffffffffffffffffffff003020" & _
    "300c06082a864886f70d020205000410" & _
    "dca9ecf1c15c1bd266aff9c8799365cd")
ct = rsaRawPrivate(pt, strPrivateKey)
Debug.Print "CT=" & cnvHexStrFromBytes(ct)

Dim strPublicKey As String
Dim dt() As Byte
strPublicKey = rsaReadPublicKey("Rsa508.pub")
Debug.Assert Len(strPublicKey) > 0
dt = rsaRawPublic(ct, strPublicKey)
Debug.Print "DT=" & cnvHexStrFromBytes(dt)
```

### See Also

[RSA_RawPublic](#RSA_RawPublic)
[RSA_EncodeMsg](#RSA_EncodeMsg)
[Raw RSA Techniques](#rawrsa)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_RawPublic"></a>RSA_RawPublic
---------------------------------------

Transforms (that is, encrypts or decrypts) raw data using an RSA public key.

### VBA/VB6 Syntax

`Public Declare Function RSA_RawPublic Lib "diCrPKI.dll" 
    (ByRef lpData As Byte, ByVal nDataLen As Long, 
    ByVal strPublicKey As String, ByVal nOptions As Long) As Long`

`nRet = RSA_RawPublic(lpData(0), nDataLen, strPublicKey, nOptions)`

### C/C++ Syntax

`long __stdcall RSA_RawPublic(unsigned char *lpData, long nDataLen, const char *szPublicKey, long nOptions);`

### Parameters

*lpData*
:   [in,out] array containing the data to be transformed.

*nDataLen*
:   [in] specifying the number of bytes of data.

*szPublicKey*
:   [in] containing the RSA public key string.

*nOptions*
:   [in] option flags. Set to zero.

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`rsaRawPublic`](#VB_rsaRawPublic) (lpData() As Byte, szPublicKey As String, Optional nOptions As Long = 0) As Byte()

### .NET Equivalent

[Rsa.RawPublic Method](#M_Rsa_RawPublic_ByteString) (Byte[], String)  
[Rsa.RawPublic Method](#M_Rsa_RawPublic_ByteStringInt32) (Byte[], String, Int32)  

### C++ (STL) Equivalent

static bvec_t [dipki::Rsa::RawPublic](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#aa9095099ada24c1489840cfa53ec83e3 "External link") (const bvec_t &data, const std::string &keyStr)

### Python Equivalent

static [Rsa.raw_public](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.raw_public "External link")(block, pubkeystr)

### Remarks

The data must be the same length as the RSA key modulus (use `RSA_KeyBytes()` to find out this).
The output is written over the input. The RSA public key must be provided in the internal key string format.

### Example (VBA core function)

This is from Example 4.2 of  [[SMIME-EX]](#SMIME-EX):

```

Dim sEncDataHex As String
Dim abData() As Byte
Dim nDataLen As Long
Dim strCertFile As String
Dim nKeyLen As Long
Dim strPublicKey As String
Dim nRet As Long

' Cut and paste from DUMPASN1 output
sEncDataHex = "2F 23 82 D2 F3 09 5F B8 0C 58 EB 4E" & _
    "9D BF 89 9A 81 E5 75 C4 91 3D D3 D0" & _
    "D5 7B B6 D5 FE 94 A1 8A AC E3 C4 84" & _
    "F5 CD 60 4E 27 95 F6 CF 00 86 76 75" & _
    "3F 2B F0 E7 D4 02 67 A7 F5 C7 8D 16" & _
    "04 A5 B3 B5 E7 D9 32 F0 24 EF E7 20" & _
    "44 D5 9F 07 C5 53 24 FA CE 01 1D 0F" & _
    "17 13 A7 2A 95 9D 2B E4 03 95 14 0B" & _
    "E9 39 0D BA CE 6E 9C 9E 0C E8 98 E6" & _
    "55 13 D4 68 6F D0 07 D7 A2 B1 62 4C" & _
    "E3 8F AF FD E0 D5 5D C7"

' Convert to bytes
abData = cnvBytesFromHexStr(sEncDataHex)
' Check
Debug.Print cnvHexStrFromBytes(abData)

strCertFile = "AliceRSASignByCarl.cer"
' Read in PublicKey as base64 string - pre-dimension first
nKeyLen = RSA_GetPublicKeyFromCert("", 0, strCertFile, 0)
Debug.Print "KeyLen = " & nKeyLen
If nKeyLen <= 0 Then
    Debug.Print pkiGetLastError()
    MsgBox "Unable to retrieve private key"
    Exit Function
End If
' Pre-dimension the string to receive data
strPublicKey = String(nKeyLen, " ")
' Read in the Key
nRet = RSA_GetPublicKeyFromCert(strPublicKey, nKeyLen, strCertFile, 0)
Debug.Print "PubKey= " & strPublicKey

' Verify using the public key
nDataLen = UBound(abData) + 1
Debug.Print "Input:  " & cnvHexStrFromBytes(abData)
nRet = RSA_RawPublic(abData(0), nDataLen, strPublicKey, 0)
Debug.Print "Output: " & cnvHexStrFromBytes(abData)

```

Stripping the PKCS-1.5 header `0001FFFF...FF00` from the output, we should get

```

3021300906052B0E03021A05000414406AEC085279BA6E16022D9E0629C0229687DD48

```

which is a DigestInfo containing the 20-byte SHA-1 hash

```

406AEC085279BA6E16022D9E0629C0229687DD48

```

### Example (VBA wrapper function)

```

Dim strPrivateKey As String
Dim pt() As Byte
Dim ct() As Byte
strPrivateKey = rsaReadPrivateKey("rsa508.p8e", "password")
Debug.Assert Len(strPrivateKey) > 0
pt = cnvBytesFromHexStr("0001ffffffffffffffffffffffffffff" & _
    "ffffffffffffffffffffffffff003020" & _
    "300c06082a864886f70d020205000410" & _
    "dca9ecf1c15c1bd266aff9c8799365cd")
ct = rsaRawPrivate(pt, strPrivateKey)
Debug.Print "CT=" & cnvHexStrFromBytes(ct)

Dim strPublicKey As String
Dim dt() As Byte
strPublicKey = rsaReadPublicKey("Rsa508.pub")
Debug.Assert Len(strPublicKey) > 0
dt = rsaRawPublic(ct, strPublicKey)
Debug.Print "DT=" & cnvHexStrFromBytes(dt)
```

### See Also

[RSA_RawPrivate](#RSA_RawPrivate)
[RSA_EncodeMsg](#RSA_EncodeMsg)
[Raw RSA Techniques](#rawrsa)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_ReadAnyPrivateKey"></a>RSA_ReadAnyPrivateKey
-------------------------------------------------------

Reads from a file or string containing a private key into an "internal" private key string.

### VBA/VB6 Syntax

`Public Declare Function RSA_ReadAnyPrivateKey Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strKeyFileOrString As String, ByVal strPassword As String, ByVal nOptions As Long) As Long`

`nRet = RSA_ReadAnyPrivateKey(strOutput, nOutChars, strKeyFileOrString, strPassword, nOptions) As Long`

### C/C++ Syntax

`long __stdcall RSA_ReadAnyPrivateKey(char *szOutput, long nOutChars, const char *szKeyFileOrString, const char *szPassword, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive encoded private key data in "internal" format.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szKeyFileOrString*
:   [in] specifying either the name of file containing the private key 
	or a string containing the key in [PEM format](#pemstring) or XML format.

*szPassword*
:   [in] containing the password, if the key is encrypted, or `""` if not encrypted.

*nOptions*
:   [in] not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`rsaReadAnyPrivateKey`](#VB_rsaReadAnyPrivateKey) (szKeyFileOrString As String, Optional szPassword As String = "", Optional nOptions As Long = 0) As String  
Public Function [`rsaReadPrivateKey`](#VB_rsaReadPrivateKey) (szKeyFileOrString As String, Optional szPassword As String = "", Optional nOptions As Long = 0) As String

### .NET Equivalent

[Rsa.ReadPrivateKey Method](#M_Rsa_ReadPrivateKey)  

### C++ (STL) Equivalent

static std::string [dipki::Rsa::ReadPrivateKey](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a1e2eff6eac9764624ed7d9eaf23b8f7a "External link") (const std::string &keyFileOrString, const std::string &password="")

### Python Equivalent

static [Rsa.read_private_key](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.read_private_key "External link")(keyfileorstr, password="")

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

This function will attempt to read the private key from "any" supported format. 
The output will be an ephemeral "internal" key string suitable for the current session only.

Supported formats are:

* Encrypted or unencrypted PKCS#8 private key (.p8e, .p8) file in either binary DER format or text PEM format
* PKCS#12 (.p12, .pfx) file containing a PKCSShroudedKeyBag. *[v20.5]* Added support for AES256-SHA256 encryption.
* OpenSSL-compatible PKCS#1 RSA private key file in either binary DER format or text PEM format
* String containing contents of any of the above files in text form as a [PEM string](#pemstring)
* XML file or string containing an XKMS-conforming `RSAKeyPair` element
* JSON file or string containing a plaintext RSA private key represented in JSON Web Key (JWK) format.

This supersedes the following functions:

* `RSA_ReadEncPrivateKey`
* `RSA_ReadPrivateKeyInfo`
* `RSA_ReadPrivateKeyFromPFX`

### Example (VBA core function)

This VB6/VBA wrapper function returns the "internal" private key string given the filename and password

```

Public Function rsaReadPrivateKey(strKeyFileOrString As String, strPassword As String) As String
' Reads the private key from any supported private key file or PEM string
' Returns the key as an ephemeral base64 string or an empty string on error
    Dim nChars As Long
    ' How long is PrivateKey string?
    nChars = RSA_ReadAnyPrivateKey("", 0, strKeyFileOrString, strPassword, 0)
    If nChars <= 0 Then
        Exit Function
    End If
    ' Pre-dimension the string to receive data
    rsaReadPrivateKey = String(nChars, " ")
    ' Read in the Private Key
    nChars = RSA_ReadAnyPrivateKey(rsaReadPrivateKey, nChars, strKeyFileOrString, strPassword, 0)
End Function

```

### Example (VBA wrapper function)

```

Dim strIntKey As String

strIntKey = rsaReadAnyPrivateKey("AlicePrivRSASign.p8e", "password")
Debug.Print strIntKey
Debug.Print "KeyHashCode=0x" & Hex(RSA_KeyHashCode(strIntKey))
' Unencrypted key
strIntKey = rsaReadAnyPrivateKey("AlicePrivRSASign.pri", "")
Debug.Print strIntKey
Debug.Print "KeyHashCode=0x" & Hex(RSA_KeyHashCode(strIntKey))
' Key in XML form
strIntKey = rsaReadAnyPrivateKey("alice-pri.xml", "")
Debug.Print strIntKey
Debug.Print "KeyHashCode=0x" & Hex(RSA_KeyHashCode(strIntKey))

```

### See Also

[RSA_ReadAnyPublicKey](#RSA_ReadAnyPublicKey)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_ReadAnyPublicKey"></a>RSA_ReadAnyPublicKey
-----------------------------------------------------

Reads from a file or string containing a public key into an "internal" public key string.

### VBA/VB6 Syntax

`Public Declare Function RSA_ReadAnyPublicKey Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strKeyFileOrString As String, ByVal nOptions As Long) As Long`

`nRet = RSA_ReadAnyPublicKey(strOutput, nOutChars, strKeyFileOrString, nOptions) As Long`

### C/C++ Syntax

`long __stdcall RSA_ReadAnyPublicKey(char *szOutput, long nOutChars, const char *szKeyFileOrString, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive encoded public key data in "internal" format.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szKeyFileOrString*
:   [in] specifying the name of file containing the key 
	or a string containing the key in [PEM format](#pemstring) or XML format.

*nOptions*
:   [in] not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`rsaReadAnyPublicKey`](#VB_rsaReadAnyPublicKey) (szKeyFileOrString As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Rsa.ReadPublicKey Method](#M_Rsa_ReadPublicKey)  

### C++ (STL) Equivalent

static std::string [dipki::Rsa::ReadPublicKey](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a2d73a8d0f5c72a5c8328d290351bedb6 "External link") (const std::string &keyFileOrString)

### Python Equivalent

static [Rsa.read_public_key](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.read_public_key "External link")(keyfileorstr)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

This function will attempt to read the public key from "any" supported format. 
The output will be an ephemeral "internal" key string suitable for the current session only.

Supported formats are:

* X.509 certificate (.cer, .crt) file in either binary DER format or text PEM format
* String containing the contents of an X.509 certificate file in base64 encoding
* PKCS#1 RSA Public Key (.p1) file in either binary DER format or text PEM format
* File containing X.509 SubjectPublicKeyInfo data (OpenSSL public key) in either binary DER format or text PEM format
* String containing contents of any of the above files in text form as a [PEM string](#pemstring)
* XML file or string containing an XKMS-conforming `RSAKeyValue` or `RSAKeyPair` element
* JSON file or string containing a plaintext RSA public key represented in JSON Web Key (JWK) format.

To read in a public key from a PFX/p12 file, use `[RSA_ReadAnyPrivateKey](#RSA_ReadAnyPrivateKey)`
then `[RSA_PublicKeyFromPrivate](#RSA_PublicKeyFromPrivate)`.

This supersedes the following functions:

* `RSA_ReadPublicKey`
* `RSA_GetPublicKeyFromCert`

### Example (VBA core function)

This VB6/VBA wrapper function returns the "internal" public key string from the specified file.

```

Public Function rsaReadPublicKey(strKeyFile As String) As String
' Reads the public key from any supported public key file or PEM string
' Returns the key as an ephemeral base64 string or an empty string on error
    Dim nChars As Long
    ' How long is key string?
    nChars = RSA_ReadAnyPublicKey("", 0, strKeyFile, 0)
    If nChars <= 0 Then
        Exit Function
    End If
    ' Pre-dimension the string to receive data
    rsaReadPublicKey = String(nChars, " ")
    ' Read in the Public Key
    nChars = RSA_ReadAnyPublicKey(rsaReadPublicKey, nChars, strKeyFile, 0)
End Function

```

This example reads in an RSA public key in JSON JWK format.

```

Dim strJson As String
Dim strPublicKey As String
Dim nChars As Long

' RSA public key as a JSON string
' Ref: RFC 7517 JSON Web Key (JWK) Appendix A.1
' NB quotation marks (") inside a VBA string are escaped as "".
strJson = "{""kty"":""RSA""," & _
    """n"": ""0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx" & _
    "4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMs" & _
    "tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2" & _
    "QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI" & _
    "SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqb" & _
    "w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw""," & _
    """e"":""AQAB""," & _
    """alg"":""RS256""," & _
    """kid"":""2011-04-29""}"

Debug.Print strJson
' Read in the public key as an internal string
' How many characters?
nChars = RSA_ReadAnyPublicKey(ByVal 0&, 0, strJson, 0)
Debug.Print "RSA_ReadAnyPublicKey returns " & nChars
strPublicKey = String(nChars, " ")
nChars = RSA_ReadAnyPublicKey(strPublicKey, nChars, strJson, 0)
' Examine the key's properties
Debug.Print "RSA key size = " & RSA_KeyBits(strPublicKey) & " bits"
Debug.Print "Hash code = 0x" & Hex(RSA_KeyHashCode(strPublicKey))

```

```

{"kty":"RSA","n": "0vx7agoebGcQSuuPiLJXZptN9nndr [cut] JzKnqDKgw","e":"AQAB","alg":"RS256","kid":"2011-04-29"}
RSA_ReadAnyPublicKey returns 400
RSA key size = 2048 bits
Hash code = 0xDFC04E17

```

### Example (VBA wrapper function)

```

Dim strIntKey As String

strIntKey = rsaReadAnyPublicKey("AlicePubRSA.pub")
Debug.Print strIntKey
Debug.Print "KeyHashCode=0x" & Hex(RSA_KeyHashCode(strIntKey))
' X.509 certificate
strIntKey = rsaReadAnyPublicKey("AliceRSASignByCarl.cer")
Debug.Print strIntKey
Debug.Print "KeyHashCode=0x" & Hex(RSA_KeyHashCode(strIntKey))
' Key in XML form
strIntKey = rsaReadAnyPublicKey("alice-pub.xml")
Debug.Print strIntKey
Debug.Print "KeyHashCode=0x" & Hex(RSA_KeyHashCode(strIntKey))

```

### See Also

[RSA_ReadAnyPublicKey](#RSA_ReadAnyPublicKey)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_ReadEncPrivateKey"></a>RSA_ReadEncPrivateKey
-------------------------------------------------------

Reads from an encrypted PKCS#8 private key info file into an "internal" private key string.
*[Superseded by* `[RSA_ReadAnyPrivateKey](#RSA_ReadAnyPrivateKey)`.]

### VBA/VB6 Syntax

`Public Declare Function RSA_ReadEncPrivateKey Lib "diCrPKI.dll" 
    (ByVal strPrivateKey As String, ByVal nOutChars As Long, ByVal strEpkFileName As String, 
    ByVal strPassword As String, ByVal nOptions As Long) As Long`

`nRet = RSA_ReadEncPrivateKey(strPrivateKey, nOutChars, 
    strEpkFileName, strPassword, nOptions) As Long`

### C/C++ Syntax

`long __stdcall RSA_ReadEncPrivateKey(char *szOutput, long nOutChars, const char *szEpkFile, const char *szPassword, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive encoded private key data in "internal" format.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szEpkFile*
:   [in] specifying the filename of a PKCS-8 encrypted private key info
file (or a string containing the key in [PEM format](#pemstring)).

*szPassword*
:   [in] containing the password

*nOptions*
:   [in] not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a negative [error code](#errorcodes).

### .NET Equivalent

[Rsa.ReadEncPrivateKey Method](#M_Rsa_ReadEncPrivateKey)  

### Remarks

Only PKCS-8 `EncryptedPrivateKeyInfo` data 
using the `rsaEncryption` algorithm is supported.
The file must be either in binary BER-encoded format or PEM format. 

### See Also

[RSA_SaveEncPrivateKey](#RSA_SaveEncPrivateKey)
[RSA_ReadPrivateKeyInfo](#RSA_ReadPrivateKeyInfo)
[RSA_SavePrivateKeyInfo](#RSA_SavePrivateKeyInfo)
[RSA_GetPrivateKeyFromPFX](#RSA_GetPrivateKeyFromPFX)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_ReadPrivateKeyFromPFX"></a>RSA_ReadPrivateKeyFromPFX
---------------------------------------------------------------

Reads a private key directly from an encrypted PFX/PKCS-12 file into an "internal" private key string. *[Superseded by* `[RSA_ReadAnyPrivateKey](#RSA_ReadAnyPrivateKey)`.]

### VBA/VB6 Syntax

`Public Declare Function RSA_ReadPrivateKeyFromPFX Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strPfxFile As String, ByVal strPassword As String, ByVal nOptions As Long) As Long`

`nRet = RSA_ReadPrivateKeyFromPFX(strOutput, nOutChars, strPfxFile, strPassword, nOptions) As Long`

### C/C++ Syntax

`long __stdcall RSA_ReadPrivateKeyFromPFX(char *szOutput, long nOutChars, const char *szPfxFile, const char *szPassword, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive private key data in "internal" encoded format.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szPfxFile*
:   [in] containing the PFX filename
	(or a string containing the PFX data in [PEM format](#pemstring))

*szPassword*
:   [in] containing the password.

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a negative [error code](#errorcodes).

### .NET Equivalent

[Rsa.ReadPrivateKeyFromPFX Method](#M_Rsa_ReadPrivateKeyFromPFX)  

### Remarks

This will read the private key from 
the first `pkcs8ShroudedKeyBag` object it finds and can decrypt in the PFX file.
The result is a string in ["internal" key string format](#internalkeys) valid only for the current session.
Call the function with an empty or NULL *szOutput* string or zero *nOutChars* parameter to find out the required length 
of the output string. C/C++ users should add one to this value when allocating memory.

If you need the public key instead from a PFX file, then use this function followed by
[`RSA_PublicKeyFromPrivate()`](#RSA_PublicKeyFromPrivate).

If you just want to extract the encrypted private key and save directly as a pkcs-8 file, then use the
[`RSA_GetPrivateKeyFromPFX()`](#RSA_GetPrivateKeyFromPFX) function.

### Example

```

Dim strPfxFile As String
Dim strPrivateKey As String
Dim strPassword As String
Dim nChars As Long
Dim nCode As Long
Dim nRet As Long

strPfxFile = "bob.pfx"
strPassword = "password"

' Read private key from PFX file into internal string form
nChars = RSA_ReadPrivateKeyFromPFX("", 0, strPfxFile, strPassword, 0)
If nChars <= 0 Then Exit Sub    ' Catch error here
strPrivateKey = String(nChars, " ")
nChars = RSA_ReadPrivateKeyFromPFX(strPrivateKey, Len(strPrivateKey), strPfxFile, strPassword, 0)

' Display some info about it
Debug.Print "Private key length = " & RSA_KeyBits(strPrivateKey) & " bits"
nCode = RSA_KeyHashCode(strPrivateKey)
Debug.Print "KeyHashCode=" & Hex(nCode)
nRet = RSA_CheckKey(strPrivateKey, 0)
Debug.Print "RSA_CheckKey returns " & nRet & ": (PKI_VALID_PRIVATEKEY=" & PKI_VALID_PRIVATEKEY & ")"

' Clean up
strPrivateKey = wipeString(strPrivateKey)
strPassword = wipeString(strPassword)

```

```

Private key length = 1024 bits
KeyHashCode=6BCC120C
RSA_CheckKey returns 0: (PKI_VALID_PRIVATEKEY=0)

```

### See Also

[RSA_GetPrivateKeyFromPFX](#RSA_GetPrivateKeyFromPFX)
[RSA_ReadEncPrivateKey](#RSA_ReadEncPrivateKey)
[RSA_PublicKeyFromPrivate](#RSA_PublicKeyFromPrivate)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_ReadPrivateKeyInfo"></a>RSA_ReadPrivateKeyInfo
---------------------------------------------------------

Reads from an (unencrypted) PKCS-8 private key info file into an "internal" private key string. 
*[Superseded by* `[RSA_ReadAnyPrivateKey](#RSA_ReadAnyPrivateKey)`.]

### VBA/VB6 Syntax

`Public Declare Function RSA_ReadPrivateKeyInfo Lib "diCrPKI.dll" 
    (ByVal strPrivateKey As String, ByVal nOutChars As Long, ByVal strPriFileName As String, 
    ByVal nOptions As Long) As Long`

`nRet = RSA_ReadPrivateKeyInfo(strPrivateKey, nOutChars, 
    strPriFileName, nOptions) As Long`

### C/C++ Syntax

`long __stdcall RSA_ReadPrivateKeyInfo(char *szOutput, long nOutChars, const char *szKeyFile, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive private key data in "internal" encoded format.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szKeyFile*
:   [in] specifying the filename of a  
`PrivateKeyInfo` file (or a string containing the key in [PEM format](#pemstring)).

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a negative [error code](#errorcodes).

### .NET Equivalent

[Rsa.ReadPrivateKeyInfo Method](#M_Rsa_ReadPrivateKeyInfo)  

### Remarks

Only PKCS-8 `PrivateKeyInfo` files 
specifying the `rsaEncryption` algorithm  are supported
together with OpenSSL-compatible `RSA PRIVATE KEY` files.
Files may be in either binary BER/DER-encoded format or PEM format.
Call the function with an empty or NULL *szOutput* string or zero *nOutChars* parameter to find out the required length of
the output string. C/C++ users should add one to this value when allocating memory.

### Example

This example reads in Bob's unencrypted private key from the file 
`BobPrivRSAEncrypt.pri` from [[SMIME-EX]](#SMIME-EX) and saves in encrypted form using the 
password "password". The default PBE algorithm `pbeWithSHAAnd3-KeyTripleDES-CBC` 
is used with an iteration count of 1000.

```

Dim strPRIFile As String
Dim strEPKFile As String
Dim strPrivateKey As String
Dim strPK1 As String
Dim nKeyLen As String
Dim nRet As Long

' Read in Bob's unencrypted PrivateKeyInfo data
strPRIFile = "BobPrivRSAEncrypt.pri"
nKeyLen = RSA_ReadPrivateKeyInfo("", 0, strPRIFile, 0)
If nKeyLen <= 0 Then
    MsgBox "Failed to read Private Key file"
    Exit Sub
End If
strPrivateKey = String(nKeyLen, " ")
nRet = RSA_ReadPrivateKeyInfo(strPrivateKey, nKeyLen, strPRIFile, 0)
If nRet <= 0 Then
    MsgBox "Failed to read Private Key file"
    Exit Sub
End If
' Now we save it with a password
strEPKFile = "BobPrivRSAEncrypt.p8e"
nRet = RSA_SaveEncPrivateKey(strEPKFile, strPrivateKey, 1000, "password", 0)
Debug.Print "RSA_SaveEncPrivateKey returns " & nRet

' Check we can read it
strPK1 = rsaReadPrivateKey(strEPKFile, "password")

' Sneak a look at the two key strings.
' CAUTION: _Never_ print these in a production system!
Debug.Print strPK1
Debug.Print strPrivateKey

' To compare these strings, use the RSA_KeyHashCode function
Debug.Print Hex(RSA_KeyHashCode(strPK1))
Debug.Print Hex(RSA_KeyHashCode(strPrivateKey))
If RSA_KeyHashCode(strPK1) = RSA_KeyHashCode(strPrivateKey) Then
    Debug.Print "Key string values match."
Else
    Debug.Print "ERROR: key strings do not match."
End If

```

### See Also

[RSA_ReadEncPrivateKey](#RSA_ReadEncPrivateKey)
[RSA_KeyHashCode](#RSA_KeyHashCode)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_ReadPublicKey"></a>RSA_ReadPublicKey
-----------------------------------------------

Reads from an RSA public key file into an "internal" public key string.
*[Superseded by* `[RSA_ReadAnyPublicKey](#RSA_ReadAnyPublicKey)`.]

### VBA/VB6 Syntax

`Public Declare Function RSA_ReadPublicKey Lib "diCrPKI.dll" 
    (ByVal strPublicKey As String, ByVal nOutChars As Long, ByVal strKeyFileName As String, 
    ByVal nOptions As Long) As Long`

`nRet = RSA_ReadPublicKey(strPublicKey, nOutChars, 
    strKeyFileName, nOptions) As Long`

### C/C++ Syntax

`long __stdcall RSA_ReadPublicKey(char *szOutput, long nOutChars, const char *szPubKeyFile, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive public key data in encoded "internal" format.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szPubKeyFile*
:   [in] specifying the filename of a public key file
	 (or a string containing the key in [PEM format](#pemstring)).

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`rsaReadPublicKey`](#VB_rsaReadPublicKey) (szKeyFileOrString As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Rsa.ReadPublicKey Method](#M_Rsa_ReadPublicKey)  

### Remarks

Both PKCS-1 `RSAPublicKey` and OpenSSL `SubjectPublicKeyInfo` formats are supported.
The file can be in binary BER-encoded format or PEM format, or be passed as a string containing the data in [PEM format](#pemstring). 
Call the function with an empty or NULL *szOutput* string or zero *nOutChars* parameter to find out the required length of
the output string. C/C++ users should add one to this value when allocating memory.

### Example

### See Also

[RSA_ReadAnyPublicKey](#RSA_ReadAnyPublicKey)
[RSA_SavePublicKey](#RSA_SavePublicKey)
[RSA_GetPublicKeyFromCert](#RSA_GetPublicKeyFromCert)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_SaveEncKey"></a>RSA_SaveEncKey
-----------------------------------------

Save an internal RSA key string to an encrypted key file.

### VBA/VB6 Syntax

`Public Declare Function RSA_SaveEncKey Lib "diCrPKI.dll" (ByVal strFileOut As String, ByVal strIntKeyString As String, ByVal strPassword As String, ByVal strParams As String, ByVal nOptions As Long) As Long`

`nRet = RSA_SaveEncKey(strFileOut, strIntKeyString, strPassword, strParams, nOptions) As Long`

### C/C++ Syntax

`long __stdcall RSA_SaveEncKey(const char *szFileOut, const char *szIntKeyString, const char *szPassword, const char *szParams, long nOptions);`

### Parameters

*szFileOut*
:   [in] Name of output file to be created.

*szIntKeyString*
:   [in] The private RSA key as an internal key string.

*szPassword*
:   [in] Password for encrypted private key (required).

*szParams*
:   [in] Optional parameters. Set as the empty string `""` for defaults.
	Otherwise include a set of attribute-value pairs separated by a semi-colon ";" to set options from the following
* `count=<nnn>` to set the iteration count in the encrypted private key used in the PBKDF method,
	e.g. `"count=5000;"` [default=`2048`]
* `prf=<hmac-name>` to change the HMAC algorithm used in the PBKDF2 method,
	e.g. `"prf=hmacWithSHA256;"` [default=`hmacwithSHA1`]

Valid values for hmac-name are `{hmacWithSHA1|hmacWithSHA224|hmacWithSHA256|hmacWithSHA384|hmacWithSHA512}`.

*nOptions*
:   [in] option flags: to specify the PBE algorithm. Select one of:  

`PKI_PBE_SHA_3DES` (0) to use `pbeWithSHAAnd3-KeyTripleDES-CBC` from PKCS12 (default)  

`PKI_PBE_PBKDF2_DESEDE3` for PBKDF2 using `des-EDE3-CBC`  

`PKI_PBE_PBKDF2_AES128` for PBKDF2 using `aes128-CBC`  

`PKI_PBE_PBKDF2_AES192` for PBKDF2 using `aes192-CBC`  

`PKI_PBE_PBKDF2_AES256` for PBKDF2 using `aes256-CBC`  

(there are more options - see [security options for encrypted private keys](#encryptedkeyoptions))  

and optionally add 

`PKI_KEY_FORMAT_PEM` to export an `ENCRYPTED PRIVATE KEY` PEM-format file (default is binary BER-encoded format).

### Returns (VBA/C)

If successful, the return value is zero; otherwise it returns a nonzero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`rsaSaveEncKey`](#VB_rsaSaveEncKey) (szOutputFile As String, szKeyStr As String, szPassword As String, Optional szParams As String = "", Optional nOptions As Long = 0) As Long

### .NET Equivalent

[Rsa.SaveEncKey Method](#M_Rsa_SaveEncKey)  

### C++ (STL) Equivalent

static int [dipki::Rsa::SaveEncKey](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a444982f3c1f80e8971f464eac6f47a26 "External link") (const std::string &outputFile, const std::string &keyStr, const std::string &password, PbeScheme pbes=PbeScheme::Default, const std::string &paramString="", Format fileFormat=Format::Binary)

### Python Equivalent

static [Rsa.save_enc_key](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.save_enc_key "External link")(outputfile, intkeystr, password, pbescheme=0, params='', fileformat=0)

### Remarks

*[New in v20.3]*

### Example

### See Also

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_SaveEncPrivateKey"></a>RSA_SaveEncPrivateKey
-------------------------------------------------------

Saves a private key string to a PKCS-8 encrypted private key info file.

### VBA/VB6 Syntax

`Public Declare Function RSA_SaveEncPrivateKey Lib "diCrPKI.dll" 
    (ByVal strOutputFile As String, ByVal strPrivateKey As String, ByVal nCount As Long, 
    ByVal strPassword As String, ByVal nOptions As Long) As Long`

`nRet = RSA_SaveEncPrivateKey(strOutputFile, strPrivateKey, 
   	nCount, strPassword, nOptions) As Long`

### C/C++ Syntax

`long __stdcall RSA_SaveEncPrivateKey(const char *szFileOut, const char *szKeyString, long nCount, const char *szPassword, long nOptions);`

### Parameters

*szFileOut*
:   [in] specifying the filename of the output file to be created.

*szKeyString*
:   [in] containing the private key string

*nCount*
:   [in] specifying the number of iterations to carry out

*szPassword*
:   [in] containing the password

*nOptions*
:   [in] option flags: to specify the PBE algorithm. Select one of:  

`PKI_PBE_SHA_3DES` (0) to use `pbeWithSHAAnd3-KeyTripleDES-CBC` (default)  

`PKI_PBE_PBKDF2_DESEDE3` for PBKDF2 using `des-EDE3-CBC`  

`PKI_PBE_PBKDF2_AES128` for PBKDF2 using `aes128-CBC`  

`PKI_PBE_PBKDF2_AES192` for PBKDF2 using `aes192-CBC`  

`PKI_PBE_PBKDF2_AES256` for PBKDF2 using `aes256-CBC`  

(there are more options - see [security options for encrypted private keys](#encryptedkeyoptions))  

and optionally add  

`PKI_KEY_FORMAT_PEM` to export an `ENCRYPTED PRIVATE KEY` PEM-format file (default is binary BER-encoded format).

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

[Rsa.SaveEncPrivateKey Method](#M_Rsa_SaveEncPrivateKey_StringStringInt32StringRsa_PbeOptionsRsa_Format)  
[Rsa.SaveEncPrivateKey Method](#M_Rsa_SaveEncPrivateKey_StringStringInt32StringCipherAlgorithmHashAlgorithmRsa_Format)  

### Remarks

The default is to save as a binary BER-encoded PKCS-8 EncryptedPrivateKeyInfo file.
If the `PKI_KEY_FORMAT_PEM` option is added, the file be will in PEM format.
The PEM encrypted private key format uses the header and footer lines:

```

 -----BEGIN ENCRYPTED PRIVATE KEY-----
 -----END ENCRYPTED PRIVATE KEY-----

```

### Example

This example reads Carl's unencrypted private key info file from 
[[SMIME-EX]](#SMIME-EX) and saves in encrypted format with the password "password".
It then checks that the two keys match by using the 
`[RSA_KeyHashCode](#RSA_KeyHashCode)` function.

```

Dim strPRIFile As String
Dim strEPKFile As String
Dim strPrivateKey As String
Dim strPK1 As String
Dim nChars As String
Dim nRet As Long

strPRIFile = "CarlPrivRSASign.pri"

' Read in Carl's unencrypted PrivateKeyInfo data
nChars = RSA_ReadPrivateKeyInfo("", 0, strPRIFile, 0)
If nChars <= 0 Then
    MsgBox "Failed to read Private Key file"
    Exit Sub
End If
' Dimension the string to receive it - IMPORTANT
strPrivateKey = String(nChars, " ")
' Read in as an "internal" key string
nRet = RSA_ReadPrivateKeyInfo(strPrivateKey, nChars, strPRIFile, 0)
If nRet <= 0 Then
    MsgBox "Failed to read Private Key file"
    Exit Sub
End If
Debug.Print "Private key length is " & RSA_KeyBits(strPrivateKey) & " bits"

' Now save it in PKCS#8 encrypted form with a password
strEPKFile = "CarlPrivRSASign.p8e"
nRet = RSA_SaveEncPrivateKey(strEPKFile, strPrivateKey, 1000, "password", 0)
Debug.Print "RSA_SaveEncPrivateKey returns " & nRet & " (expected 0)"

' Check we can read it (note easier wrapper function)
strPK1 = rsaReadPrivateKey(strEPKFile, "password")
If Len(strPK1) > 0 Then
    Debug.Print "Encrypted private key is " & RSA_KeyBits(strPK1) & " bits"
Else
    MsgBox "Unable to read encrypted private key"
End If

' To compare these strings, use the RSA_KeyHashCode function
Debug.Print "HashCode(original prikeyinfo) =" & Hex(RSA_KeyHashCode(strPrivateKey))
Debug.Print "HashCode(encrypted prikeyinfo)=" & Hex(RSA_KeyHashCode(strPK1))
If RSA_KeyHashCode(strPK1) = RSA_KeyHashCode(strPrivateKey) Then
    Debug.Print "OK, Key string values match."
Else
    Debug.Print "ERROR: key strings do not match."
End If

```

This should give the output

```

Private key length is 1024 bits
RSA_SaveEncPrivateKey returns 0 (expected 0)
Encrypted private key is 1024 bits
HashCode(original prikeyinfo) =A937B1B5
HashCode(encrypted prikeyinfo)=A937B1B5
OK, Key string values match.

```

### See Also

[RSA_ReadEncPrivateKey](#RSA_ReadEncPrivateKey)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_SavePrivateKeyInfo"></a>RSA_SavePrivateKeyInfo
---------------------------------------------------------

Saves a private key string to an (unencrypted) PKCS-8 private key info file.

### VBA/VB6 Syntax

`Public Declare Function RSA_SavePrivateKeyInfo Lib "diCrPKI.dll" 
    (ByVal strOutputFile As String, ByVal strPrivateKey As String, 
    ByVal nOptions As Long) As Long`

`nRet = RSA_SavePrivateKeyInfo(strOutputFile, strPrivateKey, 
   	nOptions) As Long`

### C/C++ Syntax

`long __stdcall RSA_SavePrivateKeyInfo(const char *szFileOut, const char *szKeyString, long nOptions);`

### Parameters

*szFileOut*
:   [in] specifying the filename of the output file to be created.

*szKeyString*
:   [in] containing the private key string

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_DEFAULT` (0) to export a binary BER-encoded file (default)  

`PKI_KEY_FORMAT_PEM` to export a PEM-like `PRIVATE KEY` file  

`PKI_KEY_FORMAT_SSL` to export an OpenSSL-compatible `RSA PRIVATE KEY` PEM file  

and optionally add

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

[Rsa.SavePrivateKeyInfo Method](#M_Rsa_SavePrivateKeyInfo)  

### Python Equivalent

static [Rsa.save_key](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.save_key "External link")(outputfile, keystr, fileformat=0)

### Remarks

**Caution:** this data is saved in unencrypted form. Do not use for a production key.

Any existing file of the specified name will be overwritten without warning.
Saves by default as a binary BER-encoded file compatible with the PKCS-8 PrivateKeyInfo format.
The PEM key format saved with the `PKI_KEY_FORMAT_PEM` option 
uses the header and footer lines:

```

 -----BEGIN PRIVATE KEY-----
 -----END PRIVATE KEY-----

```

The OpenSSL-compatible PEM key format saved with the `PKI_KEY_FORMAT_SSL` option 
uses the header and footer lines:

```

 -----BEGIN RSA PRIVATE KEY-----
 -----END RSA PRIVATE KEY-----

```

and is compatible with the PKCS-1 RSAPrivateKey format.

### Example

```

    Dim strEPKFile As String
    Dim strPRIFile As String
    Dim strPEMFile As String
    Dim strPassword As String
    Dim strPrivateKey As String
    Dim nRet As Long
    
    strEPKFile = "rsa508.p8e"
    strPRIFile = "rsa508.pri"
    strPEMFile = "rsa508.pem"
    strPassword = "password"
    
    ' Read in the deciphered private key string
    strPrivateKey = rsaReadPrivateKey(strEPKFile, strPassword)
    If Len(strPrivateKey) = 0 Then
        MsgBox "Unable to retrieve private key"
        Exit Function
    End If
    Debug.Print strPrivateKey
    
    ' Save as unencrypted PrivateKeyInfo file
    nRet = RSA_SavePrivateKeyInfo(strPRIFile, strPrivateKey, 0)
    Debug.Print "RSA_SavePrivateKeyInfo returns " & nRet
    
    ' Save as unencrypted PEM-format file
    nRet = RSA_SavePrivateKeyInfo(strPEMFile, strPrivateKey, PKI_KEY_FORMAT_PEM)
    Debug.Print "RSA_SavePrivateKeyInfo returns " & nRet

```

### See Also

[RSA_ReadPrivateKeyInfo](#RSA_ReadPrivateKeyInfo)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_SavePublicKey"></a>RSA_SavePublicKey
-----------------------------------------------

Saves a public key string to PKCS-1 public key file.

### VBA/VB6 Syntax

`Public Declare Function RSA_SavePublicKey Lib "diCrPKI.dll" 
    (ByVal strOutputFile As String, ByVal strPublicKey As String, 
    ByVal nOptions As Long) As Long`

`nRet = RSA_SavePublicKey(strOutputFile, strPublicKey, 
   	nOptions) As Long`

### C/C++ Syntax

`long __stdcall RSA_SavePublicKey(const char *szFileOut, const char *szKeyString, long nOptions);`

### Parameters

*szFileOut*
:   [in] specifying the filename of the output file to be created.

*szKeyString*
:   [in] containing the public key string (or a private key string)

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_DEFAULT` (0) to export a binary DER/BER-encoded file (default)  

`PKI_KEY_FORMAT_PEM` to export a PEM-like `"RSA PUBLIC KEY"` file  

`PKI_KEY_FORMAT_SSL` to export an OpenSSL-compatible `"PUBLIC KEY"` PEM file

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`rsaSaveKey`](#VB_rsaSaveKey) (szOutputFile As String, szKeyStr As String, Optional nOptions As Long = 0) As Long

### .NET Equivalent

[Rsa.SavePublicKey Method](#M_Rsa_SavePublicKey)  

### C++ (STL) Equivalent

static int [dipki::Rsa::SaveKey](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a2ce90bf0f13cbb2098a34b838f7f1af2 "External link") (const std::string &outputFile, const std::string &keyStr, Format fileFormat=Format::Binary)

### Remarks

Any existing file of the specified name will be overwritten without warning.
Saves by default as binary DER/BER-encoded PKCS-1 RSAPublicKey data.
The file saved with the `PKI_KEY_FORMAT_PEM` option is the same data in PEM format with
header and footer lines:

```

 -----BEGIN RSA PUBLIC KEY-----
 -----END RSA PUBLIC KEY-----

```

The file saved with the `PKI_KEY_FORMAT_SSL` option is compatible with the format used by OpenSSL.
The data is saved as X.509 SubjectPublicKeyInfo format encoded with
header and footer lines:

```

 -----BEGIN PUBLIC KEY-----
 -----END PUBLIC KEY-----

```

The OpenSSL format key is saved with "Unix" line endings and a line length of strictly 64 characters.

You can use this function to extract a public key from a private key. 
Just pass the internal private key string instead of the public key string.

### Example

See the example in [`RSA_GetPublicKeyFromCert`](#RSA_GetPublicKeyFromCert).

### See Also

[RSA_ReadPublicKey](#RSA_ReadPublicKey)
[RSA_GetPublicKeyFromCert](#RSA_GetPublicKeyFromCert)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_ToXMLString"></a>RSA_ToXMLString
-------------------------------------------

Creates an XML string representation of an RSA internal key string.

### VBA/VB6 Syntax

`Public Declare Function RSA_ToXMLString Lib "diCrPKI.dll" 
    (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strKeyString As String, 
    ByVal nOptions As Long) As Long`

`nRet = RSA_ToXMLString(strOutput, nOutChars, 
    strKeyString, nOptions) As Long`

### C/C++ Syntax

`long __stdcall RSA_ToXMLString(char *szOutput, long nOutChars, const char *szKeyString, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive XML data.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szKeyString*
:   [in] containing the RSA public or private key in internal format

*nOptions*
:   [in] option flags: Select and combine:  

`PKI_DEFAULT` (0) to output in appropriate W3C standard format 
(`RSAKeyValue` for public key and `RSAKeyPair` for private key)  

`PKI_XML_RSAKEYVALUE`  to force private key output as .NET-compatible `RSAKeyValue` format (instead of W3C `RSAKeyPair`)  

`PKI_XML_EXCLPRIVATE` to exclude the private key (use to get a public key `RSAKeyValue` from a private key)  

`PKI_XML_HEXBINARY` to output with data in non-conforming `hexBinary` format

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`rsaToXMLString`](#VB_rsaToXMLString) (szKeyString As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Rsa.ToXMLString Method (String, Rsa.XmlOptions)](#M_Rsa_ToXMLString_StringRsa_XmlOptions)  

### C++ (STL) Equivalent

static std::string [dipki::Rsa::ToXMLString](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a33afa8224f6a3d5a3142eddb9e223b70 "External link") (const std::string &keyStr, XmlOptions opts=XmlOptions::None, const std::string &prefix="")

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

**Caution:** the private key is saved in unencrypted form. Do not use for a production key.

Both public and private key data can be output. The key must have been read first into an internal
key string using one of the other RSA key input functions in this toolkit.

If the internal key is a public key, or if the `PKI_XML_EXCLPRIVATE` option is used with a private key,
the output will always be a `RSAKeyValue` element
containing just `<Modulus>` and `<Exponent>` elements
as per [[XMLDSIG](#XMLDSIG)].

If the internal key is a private key and the `PKI_XML_EXCLPRIVATE` option is *not* used,
the default output will be a a [XKMS](#XKMS)-conforming `RSAKeyPair` element with the private key
parameters included. Including the `PKI_XML_RSAKEYVALUE` option will force a .NET-compatible
`RSAKeyValue` element instead. 
The only difference between `RSAKeyPair` and `RSAKeyValue` is in the name of the
outer XML element. The default behaviour is to comply with the W3C standards 
[[XKMS](#XKMS)] and [[XMLDSIG](#XMLDSIG)].
Users who wish to export a private key to use in the .NET world will 
probably want to use the `PKI_XML_RSAKEYVALUE` option.

The `PKI_XML_HEXBINARY` option will output the binary data in `hexBinary` encoding format
instead of base64. This latter format is not in conformance with any W3C standard, but is provided to allow
users to see the data in more readable hex format. Such a format can be read by  
this toolkit's [`RSA_FromXMLString()`](#RSA_FromXMLString) function,
but don't try using it anywhere else.

### Example (VBA core function)

This example reads in a private key from a encrypted private key file and then 
converts to an XML string in the .NET-compatible format.

```

    Dim strEPKFile As String
    Dim strPassword As String
    Dim strPrivateKey As String
    Dim strXML As String
    Dim nLen As Long

    strEPKFile = "AlicePrivRSASign.p8e"
    strPassword = "password"
    
    ' Read in the deciphered private key string in our internal format
    strPrivateKey = rsaReadPrivateKey(strEPKFile, strPassword)
    If Len(strPrivateKey) = 0 Then
        MsgBox "Unable to retrieve private key"
        Exit Function
    End If
    Debug.Print "INTKEY=" & strPrivateKey
    
    ' Convert to XML
    nLen = RSA_ToXMLString("", 0, strPrivateKey, PKI_XML_RSAKEYVALUE)
    ' pre-dimension first
    strXML = String(nLen, " ")
    nLen = RSA_ToXMLString(strXML, Len(strXML), strPrivateKey, PKI_XML_RSAKEYVALUE)
    strXML = Left(strXML, nLen)    
    Debug.Print "XML=" & strXML

```

The output should look like this (only longer):

```

INTKEY=MIICXAIBAAKBgQDgiXM5jdj19eiHdjl/ ...
XML=<RSAKeyValue><Modulus>4IlzOY3Y9fXoh ... +yRRKt/IQ==</D></RSAKeyValue>

```

### Example (VBA wrapper function)

```

Dim strPrivateKey As String
strPrivateKey = rsaReadPrivateKey("AlicePrivRSASign.p8e", "password")
Debug.Print rsaToXMLString(strPrivateKey, 0)
Debug.Print rsaToXMLString(strPrivateKey, PKI_XML_EXCLPRIVATE Or PKI_XML_HEXBINARY)
Debug.Print rsaToXMLStringEx(strPrivateKey, "ds", PKI_XML_EXCLPRIVATE)
' Now derive internal private key string from XML
Dim strXML As String
Dim strKey As String
strXML = rsaToXMLString(strPrivateKey)
strKey = rsaFromXMLString(strXML)
Debug.Print "Key length = " & RSA_KeyBits(strKey) & " bits"
```

### See Also

[RSA_FromXMLString](#RSA_FromXMLString)

[[Contents](#topofpage)] [[Index](#index)]

<a id="RSA_ToXMLStringEx"></a>RSA_ToXMLStringEx
-----------------------------------------------

Creates an XML string representation of an RSA internal key string with option to add a namespace prefix.

### VBA/VB6 Syntax

`Public Declare Function RSA_ToXMLStringEx Lib "diCrPKI.dll" 
    (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strKeyString As String, 
    ByVal strPrefix As String, ByVal nOptions As Long) As Long`

`nRet = RSA_ToXMLStringEx(strOutput, nOutChars, 
    strKeyString, "ds", nOptions) As Long`

### C/C++ Syntax

`long __stdcall RSA_ToXMLStringEx(char *szOutput, long nOutChars, const char *szKeyString, const char *szPrefix, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive XML data.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szKeyString*
:   [in] containing the RSA public or private key in internal format

*szPrefix*
:   [in] the namespace prefix to be added to all elements

*nOptions*
:   [in] option flags: Select and combine:  

`PKI_DEFAULT` (0) to output in appropriate W3C standard format 
(`RSAKeyValue` for public key and `RSAKeyPair` for private key)  

`PKI_XML_RSAKEYVALUE`  to force private key output as .NET-compatible `RSAKeyValue` format (instead of W3C `RSAKeyPair`)  

`PKI_XML_EXCLPRIVATE` to exclude the private key (use to get a public key `RSAKeyValue` from a private key)  

`PKI_XML_HEXBINARY` to output with data in non-conforming `hexBinary` format

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`rsaToXMLStringEx`](#VB_rsaToXMLStringEx) (szKeyString As String, szPrefix As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Rsa.ToXMLString Method (String, String, Rsa.XmlOptions)](#M_Rsa_ToXMLString_StringStringRsa_XmlOptions)  

### Python Equivalent

static [Rsa.to_xmlstring](https://cryptosys.net/pki/pydocpki/class-stubs/Rsa.html#cryptosyspki.Rsa.to_xmlstring "External link")(keystr, opts=0, prefix='')

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

Use this extended function to add a namespace prefix to all elements in the XML output;
for example, `<ds:RSAKeyValue>`.
Note that it's up to the user to map the prefix to a URI somewhere in the final XML document
(for reference, the correct form is `xmlns:ds="http://www.w3.org/2000/09/xmldsig#"`).

See also the remarks for [RSA_ToXMLString](#RSA_ToXMLString).

### Example (VBA core function)

```

nLen = RSA_ToXMLStringEx("", 0, strPrivateKey, "ds", PKI_XML_EXCLPRIVATE)
' pre-dimension first
strXML = String(nLen, " ")
nLen = RSA_ToXMLStringEx(strXML, Len(strXML), strPrivateKey, "ds", PKI_XML_EXCLPRIVATE)
strXML = Left(strXML, nLen)    
Debug.Print "XML=" & strXML

```

```

<ds:RSAKeyValue><ds:Modulus>uV3GoY7...Yb+F3Q==</ds:Modulus><ds:Exponent>AQAB</ds:Exponent></ds:RSAKeyValue>

```

### Example (VBA wrapper function)

```

Dim strPrivateKey As String
strPrivateKey = rsaReadPrivateKey("AlicePrivRSASign.p8e", "password")
Debug.Print rsaToXMLString(strPrivateKey, 0)
Debug.Print rsaToXMLString(strPrivateKey, PKI_XML_EXCLPRIVATE Or PKI_XML_HEXBINARY)
Debug.Print rsaToXMLStringEx(strPrivateKey, "ds", PKI_XML_EXCLPRIVATE)
' Now derive internal private key string from XML
Dim strXML As String
Dim strKey As String
strXML = rsaToXMLString(strPrivateKey)
strKey = rsaFromXMLString(strXML)
Debug.Print "Key length = " & RSA_KeyBits(strKey) & " bits"
```

### See Also

[RSA_ToXMLString](#RSA_ToXMLString)

[[Contents](#topofpage)] [[Index](#index)]

<a id="SIG_SignData"></a>SIG_SignData
-------------------------------------

Compute a signature value over data in a byte array.

### VBA/VB6 Syntax

`Public Declare Function SIG_SignData Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByRef lpData As Byte, ByVal nDataLen As Long, ByVal strKeyFile As String, ByVal strPassword As String, ByVal strAlgName As String, ByVal nOptions As Long) As Long`

`nRet = SIG_SignData(strOutput, nOutChars, lpData(0), nDataLen,
        strKeyFile, strPassword, strAlgName, nOptions)`

### C/C++ Syntax

`long __stdcall SIG_SignData(char *szOutput, long nOutChars, const unsigned char *lpData, long nDataLen, const char *szKeyFile, const char *szPassword, const char *szAlgName, long nOptions);`

### Parameters

*szOutput*
:   [out] string of sufficient length to receive the output.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*lpData*
:   [in] byte array containing the input data to be signed.

*nDataLen*
:   [in] specifying the length of the input data in bytes.

*szKeyFile*
:   [in] specifying the name of the private key file 
	(or a string containing the key in [PEM format](#pemstring), or a valid internal private key string).

*szPassword*
:   [in] containing the password for the private key, or `""` if not required.

*szAlgName*
:   [in] specifying the signature algorithm (case insensitive):  

`"sha1WithRSAEncryption"` (default - CAUTION)  

`"sha224WithRSAEncryption"`  

`"sha256WithRSAEncryption"` [minimum recommended]  

`"sha384WithRSAEncryption"`  

`"sha512WithRSAEncryption"`  

`"md5WithRSAEncryption"` [for legacy applications - not recommended for new implementations]  

`"ecdsaWithSHA1"`  

`"ecdsaWithSHA224"`  

`"ecdsaWithSHA256"`  

`"ecdsaWithSHA384"`  

`"ecdsaWithSHA512"`  

`"RSA-PSS-SHA1"`  

`"RSA-PSS-SHA224"`  

`"RSA-PSS-SHA256"`  

`"RSA-PSS-SHA384"`  

`"RSA-PSS-SHA512"`  

`"Ed25519"` *[New in v20.0]* (see Remarks)  

`"Ed448"` *[New in v22.0]* (see Remarks)  

or `""` to use the signature algorithm flag in *nOptions*, 
see [Specifying the signature algorithm in a SIG_ function](#sigalgorithm).

*nOptions*
:   [in] 
	Zero (0) for defaults.  

	Add the bitflag:
	

* `PKI_SIG_USEDIGEST` 
		to pass the digest value of the data-to-be-signed as a byte array in the *lpData* parameter instead of the data itself (except with Ed25519).

To change the format of the output (default base64 encoded), add one of:  

* `PKI_ENCODE_BASE64URL` to encode the output in the [URL-safe "base64url"](#base64url) encoding of 
		[[RFC4648](#RFC4648)]; or
* `PKI_ENCODE_HEX` to encode the output in hexadecimal (base16) encoding

Options for ECDSA signatures only:
	

* `PKI_SIG_DETERMINISTIC` to use the deterministic digital signature generation procedure 
		of [[RFC6979](#RFC6979)] for ECDSA signatures (default=random k)
* `PKI_SIG_ASN1DER` to form the signature value as a DER-encoded ASN.1 structure (as used by Bitcoin);
		(default=simple concatenation `r||s`)

Options for RSA-PSS signatures only: *[New in v12.0]* (see [RSA signature and encryption schemes](#rsaschemes))  

	Add one of the following to specify the salt length:
	

* `PKI_PSS_SALTLEN_HLEN` (0) to set the salt length to `hLen`, the length of the output of the hash function (default).
* `PKI_PSS_SALTLEN_MAX` to set the salt length to the maximum possible (OpenSSL does this by default)
* `PKI_PSS_SALTLEN_20` to set the salt length to be exactly 20 bytes regardless of the hash algorithm
* `PKI_PSS_SALTLEN_ZERO` to set the salt length to be zero

	and, optionally, add:-  

* `PKI_MGF_MGF1SHA1` to force the MGF hash function to be SHA-1 (default = same as signature hash algorithm)

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string; otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`sigSignData`](#VB_sigSignData) (lpData() As Byte, szKeyFile As String, szPassword As String, szAlgName As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Sig.SignData Method](#M_Sig_SignData)  

[Sig.SignDigest Method](#M_Sig_SignDigest)  

### C++ (STL) Equivalent

static std::string [dipki::Sig::SignData](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_sig.html#a782ee97d4d716ecdc933e4bc1c9ec36c "External link") (const bvec_t &data, const std::string &keyFileOrString, const std::string &password="", Alg alg=Alg::Default, Encoding encoding=Encoding::Base64, SigOptions opts=SigOptions::None)

static [Sig.sign_digest](https://cryptosys.net/pki/pydocpki/class-stubs/Sig.html#cryptosyspki.Sig.sign_digest "External link")(digest, keyfile, password, alg, opts=Opts.DEFAULT, encoding=Encoding.DEFAULT)

### Python Equivalent

`static [Sig.sign_data](https://cryptosys.net/pki/pydocpki/class-stubs/Sig.html#cryptosyspki.Sig.sign_data "External link")(data, keyfile, password, alg, opts=Opts.DEFAULT, encoding=Encoding.DEFAULT)`

static [Sig.sign_digest](https://cryptosys.net/pki/pydocpki/class-stubs/Sig.html#cryptosyspki.Sig.sign_digest "External link")(digest, keyfile, password, alg, opts=Opts.DEFAULT, encoding=Encoding.DEFAULT)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

Computes the signature value over the input data (or its digest value) using the private key provided. 
The default output is a continuous string of base64 characters 
suitable to include in the `<SignatureValue>` node of an [XML-DSIG](#XMLDSIG) document.
Alternative output encodings (base64url and hex) can be specified using the `PKI_ENCODE_` options.

 
The `PKI_SIG_USEDIGEST` option cannot be used with Ed25519 or Ed448. The data to be signed must be passed *in toto* to the signature function.
All options except the `PKI_ENCODE_` options are ignored for the Ed25519 and Ed448 algorithms.

### Example (VBA core function)

```

Dim strSignature As String
Dim nChars As Long
Dim strData As String
Dim abData() As Byte
Dim nDataLen As Long
Dim strKeyFile As String
Dim strPassword As String
Dim strAlgName As String

' 1) Input data = three-character ASCII string "abc"
strData = "abc"
strKeyFile = "AlicePrivRSASign.p8e"
strPassword = "password" ' CAUTION: do not hard-code passwords!
strAlgName = "sha1WithRSAEncryption"

' Convert ASCII string to byte array
abData = StrConv(strData, vbFromUnicode)
nDataLen = Len(strData)
' Find required length of output string
nChars = SIG_SignData("", 0, abData(0), nDataLen, strKeyFile, strPassword, _
  strAlgName, 0)
Debug.Print "SIG_SignData returns " & nChars & " (expected >0)"
' Allocate memory for output string
strSignature = String(nChars, " ")
nChars = SIG_SignData(strSignature, Len(strSignature), abData(0), nDataLen, _
  strKeyFile, strPassword, strAlgName, 0)
' Output base64 signature value
Debug.Print "SIG=" & strSignature

' 2) Use digest value instead of original data
' Convert known value of SHA-1("abc") in hex to an array of bytes
abData = cnvBytesFromHexStr("a9993e364706816aba3e25717850c26c9cd0d89d")
nDataLen = PKI_SHA1_BYTES
' Find required length of output string
nChars = SIG_SignData("", 0, abData(0), nDataLen, strKeyFile, strPassword, _
  strAlgName, PKI_SIG_USEDIGEST)
Debug.Print "SIG_SignData returns " & nChars & " (expected >0)"
' Allocate memory for output string
strSignature = String(nChars, " ")
nChars = SIG_SignData(strSignature, Len(strSignature), abData(0), nDataLen, _
  strKeyFile, strPassword, strAlgName, PKI_SIG_USEDIGEST)
' Output base64 signature value
Debug.Print "SIG=" & strSignature

```

This uses Alice's encrypted private key to sign the ASCII string `"abc"` using 
both the original string data (converted to a byte array)
and its digest value. The output should be

```

SIG_SignData returns 172 (expected >0)
SIG=YK1aePtKQDDsVCyJdM0V9VOE6DZVTO3Z ... AmHH6QIsDZ8R8=
SIG_SignData returns 172 (expected >0)
SIG=YK1aePtKQDDsVCyJdM0V9VOE6DZVTO3Z ... AmHH6QIsDZ8R8=

```

The following example uses an elliptic curve key to produce an ECDSA signature in hex form using
the "Deterministic" algorithm from [[RFC6979](#RFC6979)]

```

Dim nChars As Long
Dim nBits As Long
Dim strIntKey As String
Dim strHexKey As String
Dim strCurveName As String
Dim strSignature As String
Dim strData As String
Dim abData() As Byte
Dim nDataLen As Long
Dim strAlgName As String

' Ref: [RFC6979] "Deterministic Usage of the DSA and ECDSA"
' A.2.3.  ECDSA, 192 Bits (Prime Field)
  
' 1. READ IN PRIVATE KEY IN (HEX,CURVENAME) FORMAT
strHexKey = "6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4"
strCurveName = "P-192"
Debug.Print "KEYHEX: " & strHexKey
Debug.Print "CURVE: " & strCurveName
' Find required length of internal key string
nChars = ECC_ReadKeyByCurve("", 0, strHexKey, strCurveName, 0)
Debug.Print "ECC_ReadKeyByCurve returns " & nChars & " (expected +ve)"
' Dimension the string to receive output
strIntKey = String(nChars, " ")
' Read into internal key string
nChars = ECC_ReadKeyByCurve(strIntKey, Len(strIntKey), strHexKey, strCurveName, 0)
'Debug.Print "INTKEY: " & strIntKey
' Check we got the bitlength we expected
nBits = ECC_QueryKey("", 0, strIntKey, "keyBits", 0)
Debug.Print "NBITS=" & nBits

' 2. PREPARE INPUT DATA AS AN ARRAY OF BYTES
strData = "test"
strAlgName = "ecdsaWithSHA1"
' Convert ASCII string to byte array
abData = StrConv(strData, vbFromUnicode)
nDataLen = Len(strData)
  
'3. SIGN IT USING DETERMINISTIC ALGORITHM FROM [RFC6979]
' Find required length of output string
nChars = SIG_SignData("", 0, _
    abData(0), nDataLen, strIntKey, "", _
    strAlgName, PKI_SIG_DETERMINISTIC Or PKI_ENCODE_HEX)
Debug.Print "SIG_SignData returns " & nChars & " (expected >0)"
' Allocate memory for output string
strSignature = String(nChars, " ")
nChars = SIG_SignData(strSignature, Len(strSignature), _
    abData(0), nDataLen, strIntKey, "", _
    strAlgName, PKI_SIG_DETERMINISTIC Or PKI_ENCODE_HEX)

' Output hex signature value
Debug.Print "SIG=" & strSignature

```

```

KEYHEX: 6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4
CURVE: P-192
ECC_ReadKeyByCurve returns 164 (expected +ve)
NBITS=192
SIG_SignData returns 96 (expected >0)
SIG=0f2141a0ebbc44d2e1af90a50ebcfce5e197b3b7d4de036deb18bc9e1f3d7387500cb99cf5f7c157070a8961e38700b7

```

### Example (VBA wrapper function)

```

Dim lpData() As Byte
Dim strSig As String
lpData = StrConv("abc", vbFromUnicode)
strSig = sigSignData(lpData, "AlicePrivRSASign.p8e", "password", "sha1WithRSAEncryption")
Debug.Print "SIG=" & strSig
Debug.Print "OK =" & "YK1aePtKQDDsVCyJdM0V9VOE6DZVTO3Z ... AmHH6QIsDZ8R8="
```

### See Also

[SIG_SignFile](#SIG_SignFile)

[[Contents](#topofpage)] [[Index](#index)]

<a id="SIG_SignFile"></a>SIG_SignFile
-------------------------------------

Compute a signature value over data in a file.

### VBA/VB6 Syntax

`Public Declare Function SIG_SignFile Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strDataFile As String, ByVal strKeyFile As String, ByVal strPassword As String, ByVal strAlgName As String, ByVal nOptions As Long) As Long`

`nRet = SIG_SignFile(strOutput, nOutChars, strDataFile, strKeyFile, strPassword, strAlgName, nOptions)`

### C/C++ Syntax

`long __stdcall SIG_SignFile(char *szOutput, long nOutChars, const char *szDataFile, const char *szKeyFile, const char *szPassword, const char *szAlgName, long nOptions);`

### Parameters

*szOutput*
:   [out] string of sufficient length to receive the output.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szDataFile*
:   [in] specifying the file containing the input data to be signed.

*szKeyFile*
:   [in] specifying the name of the private key file 
	(or a string containing the key in [PEM format](#pemstring), or a valid internal private key string).

*szPassword*
:   [in] containing the password for the private key, or `""` if not required.

*szAlgName*
:   [in] specifying the signature algorithm (case insensitive):  

`"sha1WithRSAEncryption"` (default - CAUTION)  

`"sha224WithRSAEncryption"`  

`"sha256WithRSAEncryption"` [minimum recommended]  

`"sha384WithRSAEncryption"`  

`"sha512WithRSAEncryption"`  

`"md5WithRSAEncryption"` [for legacy applications - not recommended for new implementations]  

`"ecdsaWithSHA1"`  

`"ecdsaWithSHA224"`  

`"ecdsaWithSHA256"`  

`"ecdsaWithSHA384"`  

`"ecdsaWithSHA512"`  

`"RSA-PSS-SHA1"`  

`"RSA-PSS-SHA224"`  

`"RSA-PSS-SHA256"`  

`"RSA-PSS-SHA384"`  

`"RSA-PSS-SHA512"`  

(Note that `Ed25519` and `Ed448` are not available with this function - see Remarks)  

or `""` to use the signature algorithm flag in *nOptions*, 
see [Specifying the signature algorithm in a SIG_ function](#sigalgorithm).

*nOptions*
:   [in] 
	Zero (0) for defaults.  

To change the format of the output (default base64 encoded), add one of:  

* `PKI_ENCODE_BASE64URL` to encode the output in the [URL-safe "base64url"](#base64url) encoding of 
		[[RFC4648](#RFC4648)]; or
* `PKI_ENCODE_HEX` to encode the output in hexadecimal (base16) encoding

Options for ECDSA signatures only:
	

* `PKI_SIG_DETERMINISTIC` to use the deterministic digital signature generation procedure 
		of [[RFC6979](#RFC6979)] for ECDSA signatures (default=random k)
* `PKI_SIG_ASN1DER` to form the signature value as a DER-encoded ASN.1 structure (as used by Bitcoin);
		(default=simple concatenation `r||s`)

Options for RSA-PSS signatures only:  *[New in v12.0]* (see [RSA signature and encryption schemes](#rsaschemes))  

	Add one of the following to specify the salt length:
	

* `PKI_PSS_SALTLEN_HLEN` (0) to set the salt length to `hLen`, the length of the output of the hash function (default).
* `PKI_PSS_SALTLEN_MAX` to set the salt length to the maximum possible (OpenSSL does this by default)
* `PKI_PSS_SALTLEN_20` to set the salt length to be exactly 20 bytes regardless of the hash algorithm
* `PKI_PSS_SALTLEN_ZERO` to set the salt length to be zero

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string; otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`sigSignFile`](#VB_sigSignFile) (szDataFile As String, szKeyFile As String, szPassword As String, szAlgName As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Sig.SignFile Method](#M_Sig_SignFile)  

### C++ (STL) Equivalent

static std::string [dipki::Sig::SignFile](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_sig.html#aa011b65674d1c69b7ca1aafbb67fd0e0 "External link") (const std::string &dataFile, const std::string &keyFileOrString, const std::string &password="", Alg alg=Alg::Default, Encoding encoding=Encoding::Base64, SigOptions opts=SigOptions::None)

### Python Equivalent

static [Sig.sign_file](https://cryptosys.net/pki/pydocpki/class-stubs/Sig.html#cryptosyspki.Sig.sign_file "External link")(datafile, keyfile, password, alg, opts=Opts.DEFAULT, encoding=Encoding.DEFAULT)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

This function is identical to `[SIG_SignData](#SIG_SignData)` except the data to be signed is in a file.

The Ed25519 and Ed448 signature algorithms are not available with this function. To sign using Ed25519 or Ed448, read in the file to a byte array and use [SIG_SignData](#SIG_SignData).

### Example (VBA core function)

```

Dim strSignature As String
Dim strDataFile As String
Dim strKeyFile As String
Dim strPassword As String
Dim nChars As Long
Dim nOption As Long

'Input data = file containing the three bytes 'a', 'b', 'c'
strDataFile = "abc.txt"
strKeyFile = "AlicePrivRSASign.p8e"
strPassword = "password" ' CAUTION: do not hard-code passwords!
nOption = PKI_SIG_SHA256RSA ' Use option instead of string

' Find required length of output string
nChars = SIG_SignFile("", 0, strDataFile, strKeyFile, strPassword, "", nOption)
Debug.Print "SIG_SignFile returns " & nChars & " (expected >0)"
' Allocate memory for output string
strSignature = String(nChars, " ")
nChars = SIG_SignFile(strSignature, Len(strSignature), strDataFile, strKeyFile, strPassword, "", nOption)
' Output base64 signature value
Debug.Print "SIG=" & strSignature

```

This uses Alice's encrypted private key to sign a file using sha256WithRSAEncryption. The output should be

```

SIG_SignFile returns 172 (expected >0)
SIG=tLy6hJadL4w9JI/A/qLCG0V...peD1VHSzgu/qirjOaA=

```

### Example (VBA wrapper function)

```

Dim strSig As String
strSig = sigSignFile("abc.txt", "AlicePrivRSASign.p8e", "password", "", PKI_SIG_SHA256RSA)
Debug.Print "SIG=" & strSig
Debug.Print "OK =" & "tLy6hJadL4w9JI/A/qLCG0V...peD1VHSzgu/qirjOaA="
```

### See Also

[SIG_SignData](#SIG_SignData)

[[Contents](#topofpage)] [[Index](#index)]

<a id="SIG_VerifyData"></a>SIG_VerifyData
-----------------------------------------

Verify a signature value over data in a byte array.

### VBA/VB6 Syntax

`Public Declare Function SIG_VerifyData Lib "diCrPKI.dll" (ByVal strSignature As String, ByRef lpData As Byte, ByVal nDataLen As Long, ByVal strCertOrKeyFile As String, ByVal strAlgName As String, ByVal nOptions As Long) As Long`

`nRet = SIG_VerifyData(strSignature, lpData(0), nDataLen, strCertOrKeyFile, strAlgName, nOptions)`

### C/C++ Syntax

`long __stdcall SIG_VerifyData(const char *szSignature, const unsigned char *lpData, long nDataLen, const char *szCertOrKeyFile, const char *szAlgName, long nOptions);`

### Parameters

*szSignature*
:   [in] string containing the signature value encoded in base64.

*lpData*
:   [in] byte array containing the input data to be verified.

*nDataLen*
:   [in] specifying the length of the input data in bytes.

*szCertOrKeyFile*
:   [in] specifying the X.509 certificate or public key file 
	(or a string containing the certificate or key in [PEM format](#pemstring) 
	or [base64 representation](#base64forcert)).

*szAlgName*
:   [in] specifying the signature algorithm (case insensitive):  

`"sha1WithRSAEncryption"` (default)  

`"sha224WithRSAEncryption"`  

`"sha256WithRSAEncryption"`  

`"sha384WithRSAEncryption"`  

`"sha512WithRSAEncryption"`  

`"md5WithRSAEncryption"`  

`"ecdsaWithSHA1"`  

`"ecdsaWithSHA224"`  

`"ecdsaWithSHA256"`  

`"ecdsaWithSHA384"`  

`"ecdsaWithSHA512"`  

`"RSA-PSS-SHA1"`  

`"RSA-PSS-SHA224"`  

`"RSA-PSS-SHA256"`  

`"RSA-PSS-SHA384"`  

`"RSA-PSS-SHA512"`  

`"Ed25519"` *[New in v20.0]* (see Remarks)  

`"Ed448"` *[New in v22.0]* (see Remarks)  

or `""` to use the signature algorithm flag in *nOptions*, 
see [Specifying the signature algorithm in a SIG_ function](#sigalgorithm).

*nOptions*
:   [in] 
	Zero (0) for defaults.  

`PKI_SIG_USEDIGEST` to pass the digest value of the data-to-be-verified as a byte array in the *lpData* parameter
instead of the data itself.  

`PKI_MGF_MGF1SHA1` (RSA-PSS only) to force the MGF hash function to be SHA-1 (default = same as signature hash algorithm).

### Returns (VBA/C)

Zero (0) if the signature is valid; otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`sigVerifyData`](#VB_sigVerifyData) (szSignature As String, lpData() As Byte, szCertOrKey As String, szAlgName As String, Optional nOptions As Long = 0) As Long

### .NET Equivalent

[Sig.VerifyData Method](#M_Sig_VerifyData)  

[Sig.VerifyDigest Method](#M_Sig_VerifyDigest)  

### C++ (STL) Equivalent

static bool [dipki::Sig::VerifyData](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_sig.html#afc0d9cb74fe7cfb2ce610f5f9c8c74fc "External link") (const std::string &sigStr, const bvec_t &data, const std::string &certOrKey, Alg alg=Alg::Default, VerifyOpts opts=VerifyOpts::Default)

static [Sig.digest_is_verified](https://cryptosys.net/pki/pydocpki/class-stubs/Sig.html#cryptosyspki.Sig.digest_is_verified "External link")(sig, digest, certorkey, alg, verifyopts=VerifyOpts.DEFAULT)

### Python Equivalent

`static [Sig.data_is_verified](https://cryptosys.net/pki/pydocpki/class-stubs/Sig.html#cryptosyspki.Sig.data_is_verified "External link")(sig, data, certorkey, alg, verifyopts=VerifyOpts.DEFAULT)`

static [Sig.digest_is_verified](https://cryptosys.net/pki/pydocpki/class-stubs/Sig.html#cryptosyspki.Sig.digest_is_verified "External link")(sig, digest, certorkey, alg, verifyopts=VerifyOpts.DEFAULT)

### Remarks

A signature value is considered valid if it can be decrypted by the public key in *szCertOrKeyFile* and the 
digest of the data matches the original digest of the data in the signature.
The signature algorithm and hash algorithm used to create the signature value must be provided. 

For RSA-PSS, the MGF hash algorithm is assumed to be the same as the signature hash algorithm (see [RSA signature and encryption schemes](#rsaschemes)).
If the signature was created using `mgf1SHA1` with a signature hash algorithm other than SHA-1, then you must add the option `PKI_MGF_MGF1SHA1`. 
Other combinations of signature hash algorithm/MGF hash algorithm are not supported. 

The `PKI_SIG_USEDIGEST` option cannot be used with Ed25519 or Ed448. The data to be verified must be passed *in toto* to the verify function.

### Example

```

Dim strSignature As String
Dim strData As String
Dim abData() As Byte
Dim nDataLen As Long
Dim strCertFile As String
Dim strAlgName As String
Dim nRet As Long

' Signature to be verified
strSignature = _
"YK1aePtKQDDsVCyJdM0V9VOE6DZVTO3ZoyLV9BNcYmep0glwxU5mUQcLAUTUOETImTIN2Pp4Gffr" & _
"xqdxUoczLshnXBNhg7P4ofge+WlBgmcTCnVv27LHHZpmdEbjTg6tnPMb+2b4FvMZ0LfkMKXyiRVTmG4A" & _
"NyAmHH6QIsDZ8R8="
' Data to be verified against signature = three-character ASCII string "abc"
strData = "abc"
strCertFile = "AliceRSASignByCarl.cer"
strAlgName = "sha1WithRSAEncryption"
' Convert ASCII string to byte array
abData = StrConv(strData, vbFromUnicode)
nDataLen = Len(strData)
' Verify the signature...
nRet = SIG_VerifyData(strSignature, abData(0), nDataLen, strCertFile, strAlgName, 0)
Debug.Print "SIG_VerifyData returns " & nRet & " (expecting 0)"

```

### See Also

[SIG_VerifyFile](#SIG_VerifyFile)

[[Contents](#topofpage)] [[Index](#index)]

<a id="SIG_VerifyFile"></a>SIG_VerifyFile
-----------------------------------------

Verify a signature value over data in a file.

### VBA/VB6 Syntax

`Public Declare Function SIG_VerifyFile Lib "diCrPKI.dll" (ByVal strSignature As String, ByVal strDataFile As String, ByVal strCertOrKeyFile As String, ByVal strAlgName As String, ByVal nOptions As Long) As Long`

`nRet = SIG_VerifyFile(strSignature, strDataFile, strCertOrKeyFile, strAlgName, nOptions)`

### C/C++ Syntax

`long __stdcall SIG_VerifyFile(const char *szSignature, const char *szDataFile, const char *szCertOrKeyFile, const char *szAlgName, long nOptions);`

### Parameters

*szSignature*
:   [in] string containing the signature value encoded in base64.

*szDataFile*
:   [in] specifying the file containing the input data to be verified.

*szCertOrKeyFile*
:   [in] specifying the X.509 certificate or public key file 
	(or a string containing the certificate or key in [PEM format](#pemstring) 
	or [base64 representation](#base64forcert)).

*szAlgName*
:   [in] specifying the signature algorithm (case insensitive):  

`"sha1WithRSAEncryption"` (default)  

`"sha224WithRSAEncryption"`  

`"sha256WithRSAEncryption"`  

`"sha384WithRSAEncryption"`  

`"sha512WithRSAEncryption"`  

`"md5WithRSAEncryption"` [for legacy applications - not recommended for new implementations]  

`"ecdsaWithSHA1"`  

`"ecdsaWithSHA224"`  

`"ecdsaWithSHA256"`  

`"ecdsaWithSHA384"`  

`"ecdsaWithSHA512"`  

`"RSA-PSS-SHA1"`  

`"RSA-PSS-SHA224"`  

`"RSA-PSS-SHA256"`  

`"RSA-PSS-SHA384"`  

`"RSA-PSS-SHA512"`  

(Note that `Ed25519` and `Ed448` are not available with this function - see Remarks)  

or `""` to use the signature algorithm flag in *nOptions*, 
see [Specifying the signature algorithm in a SIG_ function](#sigalgorithm).

*nOptions*
:   [in] 
	Zero (0) for defaults.  

`PKI_MGF_MGF1SHA1` (RSA-PSS only) to force the MGF hash function to be SHA-1 (default = same as signature hash algorithm).

### Returns (VBA/C)

Zero (0) if the signature is valid; otherwise it returns a negative [error code](#errorcodes).

### .NET Equivalent

[Sig.VerifyFile Method](#M_Sig_VerifyFile)  

### C++ (STL) Equivalent

static bool [dipki::Sig::VerifyFile](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_sig.html#a4434b77b3411712a19c8cbfc0109c3ea "External link") (const std::string &sigStr, const std::string &dataFile, const std::string &certOrKey, Alg alg=Alg::Default, VerifyOpts opts=VerifyOpts::Default)

### Python Equivalent

static [Sig.file_is_verified](https://cryptosys.net/pki/pydocpki/class-stubs/Sig.html#cryptosyspki.Sig.file_is_verified "External link")(sig, datafile, certorkey, alg, verifyopts=VerifyOpts.DEFAULT)

### Remarks

This function is identical to `[SIG_VerifyData](#SIG_VerifyData)` except the data to be verified is in a file.

The Ed25519 and Ed448 signature algorithms are not available with this function. To verify using Ed25519 or Ed448, read in the file to a byte array and use [SIG_VerifyData](#SIG_VerifyData). 

### Example

```

Dim strSignature As String
Dim strDataFile As String
Dim strCertFile As String
Dim strAlgName As String
Dim nRet As Long

' Signature to be verified
strSignature = _
"tLy6hJadL4w9JI/A/qLCG0Vz1fWPIrPMWD8NGmA5wP7HHlUID54elztUYrpdm9RFeh0RCMJ618dw" & _
"BpgIutuZg2qQ2i9uMUYB0DvZvkyeD6MqmtVa4ihgc9SLqhigKeP+KB7voEi7PH3hpEr9Wa3kn4mb" & _
"PpeD1VHSzgu/qirjOaA="
' File to be verified against signature = three-character ASCII string "abc"
strDataFile = "abc.txt"
strCertFile = "AliceRSASignByCarl.cer"
strAlgName = "sha256WithRSAEncryption"
' Verify the signature over the data in the file...
nRet = SIG_VerifyFile(strSignature, strDataFile, strCertFile, strAlgName, 0)
Debug.Print "SIG_VerifyFile returns " & nRet & " (expecting 0)"

```

```

SIG_VerifyFile returns 0 (expecting 0)

```

### See Also

[SIG_VerifyData](#SIG_VerifyData)

[[Contents](#topofpage)] [[Index](#index)]

<a id="SMIME_Extract"></a>SMIME_Extract
---------------------------------------

Extract the body from an S/MIME entity.

### VBA/VB6 Syntax

`Public Declare Function SMIME_Extract Lib "diCrPKI.dll" (ByVal strFileOut As String, ByVal strFileIn As String, ByVal nOptions As Long) As Long`

`nRet = SMIME_Extract(strFileOut, strFileOut, nOptions)`

### C/C++ Syntax

`long __stdcall SMIME_Extract(const char *szFileOut, const char *szFileIn, long nOptions);`

### Parameters

*szFileOut*
:   [in] string specifying the filename of the output file to be created.

*szFileIn*
:   [in] string specifying the filename of the input file.

*nOptions*
:   [in] 
	Zero (0) for defaults.  

`PKI_SMIME_ENCODE_BASE64` to encode the output in base64 encoding (default is binary).

### Returns (VBA/C)

A positive number giving the size of the output file in bytes; or a negative [error code](#errorcodes).

### .NET Equivalent

[Smime.Extract Method](#M_Smime_Extract)  

### C++ (STL) Equivalent

static int [dipki::Smime::Extract](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_smime.html#a440c2d87ffd605a72a6ff1ee2e6b419f "External link") (const std::string &outputFile, const std::string &inputFile, Encoding encoding=Encoding::Default)

### Python Equivalent

static [Smime.extract](https://cryptosys.net/pki/pydocpki/class-stubs/Smime.html#cryptosyspki.Smime.extract "External link")(outputfile, inputfile, opts=0)

### Remarks

This is designed to extract the body from an S/MIME entity with a content type of `application/pkcs7-mime`
with base64 or binary transfer encoding. 
In practice, it will extract the body from almost any type of S/MIME (or MIME) file,
except one with quoted-printable transfer encoding.

### Example

```

nRet = SMIME_Extract("cmsalice2bob-extracted.p7m", "cmsalice2bob-smime-env.txt", 0)

```

In this example, the input S/MIME file `cmsalice2bob-smime-env.txt` was created from a
CMS enveloped-data file using [`SMIME_Wrap`](#SMIME_Wrap).
The output should be a binary file identical to the original binary CMS file.

### See Also

[SMIME_Wrap](#SMIME_Wrap)

[[Contents](#topofpage)] [[Index](#index)]

<a id="SMIME_Query"></a>SMIME_Query
-----------------------------------

Query an S/MIME entity.

### VBA/VB6 Syntax

`Public Declare Function SMIME_Query Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strFileIn As String, ByVal strQuery As String, ByVal nOptions As Long) As Long`

`nRet = SMIME_Query(strFileOut, strFileOut, strQuery, nOptions)`

### C/C++ Syntax

`long __stdcall SMIME_Query(char *szOutput, long nOutChars, const char *szFileIn, const char *szQuery, long nOptions);`

### Parameters

*szOutput*
:   [out] string of sufficient length to receive the output.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szFileIn*
:   [in] string specifying the filename of the input file.

*szQuery*
:   [in]  specifying the query (see Remarks below).

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is a positive number indicating the number of characters (bytes) in the output string, 
or number of characters required if *nOutChars* was set to zero.
If the item queried cannot be found, the return value is zero.
If there is an error (e.g. invalid input), it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`smimeQuery`](#VB_smimeQuery) (szFileIn As String, szQuery As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[Smime.Query Method](#M_Smime_Query)  

### C++ (STL) Equivalent

static std::string [dipki::Smime::Query](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_smime.html#a1f6f809a61f7ac1b8680ffdf242a6757 "External link") (const std::string &inputFile, const std::string &query)

### Python Equivalent

static [Smime.query](https://cryptosys.net/pki/pydocpki/class-stubs/Smime.html#cryptosyspki.Smime.query "External link")(filename, query)

### Remarks

Valid queries are (case-insensitive): 

| Query String | Returns |
| --- | --- |
| `content-type` | Value of Content-Type, e.g. "application/pkcs7-mime" |
| `smime-type` | Value of smime-type parameter of Content-Type, e.g. "enveloped-data" |
| `encoding` | Value of Content-Transfer-Encoding, e.g. "base64" |
| `name` | Value of name parameter of Content-Type, e.g. "smime.p7m" |
| `filename` | Value of filename parameter of Content-Disposition, e.g. "smime.p7m" |

If no value is found corresponding to the query then the zero-length empty string `""` is output.

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

### Example (VBA core function)

```

Dim strQuery As String
Dim strOutput As String
Dim nRet As Long
Dim strFileIn As String

strFileIn = "cmsalice2bob-smime-env.txt"
Debug.Print "FILE: " & strFileIn

' Make a buffer large enough to receive output
strOutput = String(512, " ")

strQuery = "content-type"
nRet = SMIME_Query(strOutput, Len(strOutput), strFileIn, strQuery, 0)
If nRet <= 0 Then Exit Sub  ' catch error
Debug.Print strQuery & "=" & Left(strOutput, nRet)

strQuery = "smime-type"
nRet = SMIME_Query(strOutput, Len(strOutput), strFileIn, strQuery, 0)
If nRet <= 0 Then Exit Sub  ' catch error
Debug.Print strQuery & "=" & Left(strOutput, nRet)

strQuery = "encoding"
nRet = SMIME_Query(strOutput, Len(strOutput), strFileIn, strQuery, 0)
If nRet <= 0 Then Exit Sub  ' catch error
Debug.Print strQuery & "=" & Left(strOutput, nRet)

strQuery = "filename"
nRet = SMIME_Query(strOutput, Len(strOutput), strFileIn, strQuery, 0)
If nRet <= 0 Then Exit Sub  ' catch error
Debug.Print strQuery & "=" & Left(strOutput, nRet)

```

```

FILE: cmsalice2bob-smime-env.txt
content-type=application/pkcs7-mime
smime-type=enveloped-data
encoding=base64
filename=smime.p7m

```

### Example (VBA wrapper function)

```

Dim strFileIn As String
Dim strQuery As String

strFileIn = "cmsalice2bob-smime-env.txt"
Debug.Print "FILE: " & strFileIn
strQuery = "content-type"
Debug.Print strQuery & "=" & smimeQuery(strFileIn, strQuery, 0)
strQuery = "smime-type"
Debug.Print strQuery & "=" & smimeQuery(strFileIn, strQuery, 0)
strQuery = "encoding"
Debug.Print strQuery & "=" & smimeQuery(strFileIn, strQuery, 0)
strQuery = "filename"
Debug.Print strQuery & "=" & smimeQuery(strFileIn, strQuery, 0)
```

### See Also

[SMIME_Extract](#SMIME_Extract)

[[Contents](#topofpage)] [[Index](#index)]

<a id="SMIME_Wrap"></a>SMIME_Wrap
---------------------------------

Wrap a CMS object in an S/MIME entity.

### VBA/VB6 Syntax

`Public Declare Function SMIME_Wrap Lib "diCrPKI.dll" (ByVal strFileOut As String, ByVal strFileIn As String, ByVal strFeatures As String, ByVal nOptions As Long) As Long`

`nRet = SMIME_Wrap(strFileOut, strFileIn, strFeatures, nOptions)`

### C/C++ Syntax

`long __stdcall SMIME_Wrap(const char *szFileOut, const char *szFileIn, const char *szFeatures, long nOptions);`

### Parameters

*szFileOut*
:   [in] string specifying the filename of the output file to be created.

*szFileIn*
:   [in] string specifying the filename of the input file.

*szFeatures*
:   [in] string to specify special features. For future use.
	Leave empty `""` or `NULL` for defaults.

*nOptions*
:   [in] 
	Zero (0) for defaults.  

`PKI_SMIME_ENCODE_BINARY` to encode the body in binary encoding (default is base64).  

`PKI_SMIME_ADDX` to add an "x-" to the content subtype.

### Returns (VBA/C)

A positive number giving the size of the output file in bytes; or a negative [error code](#errorcodes).

### .NET Equivalent

[Smime.Wrap Method](#M_Smime_Wrap)  

### C++ (STL) Equivalent

static int [dipki::Smime::Wrap](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_smime.html#a10d307291729cb54cdfdc5f4c11f3469 "External link") (const std::string &outputFile, const std::string &inputFile, Encoding encoding=Encoding::Default, AdvOpts advopts=AdvOpts::Default)

### Python Equivalent

static [Smime.wrap](https://cryptosys.net/pki/pydocpki/class-stubs/Smime.html#cryptosyspki.Smime.wrap "External link")(outputfile, inputfile, opts=0)

### Remarks

This forms an S/MIME entity with a Content-Type of `application/pkcs7-mime` from a binary CMS object.
It works in file-to-file mode only. 
The input file is expected to be a binary CMS object of type enveloped-data, signed-data or compressed-data;
otherwise it is an error. 
The type of input file is detected automatically. 
The output is a text file with the correct S/MIME headers according to [[SMIME-MSG](#SMIME-MSG)]. 
By default the body is encoded in base64.
Use the `PKI_SMIME_ENCODE_BINARY` option to encode the body in "binary" instead.

Use the `PKI_SMIME_ADDX` option to change the Content-Type to 
`application/x-pkcs7-mime` for compatibility with legacy applications.

S/MIME signed messages with the `multipart/signed` format are currently not supported.

### Example

```

nRet = SMIME_Wrap("cmsalice2bob-smime-env.txt", "cmsalice2bob.p7m", "", 0)

```

In this example, the binary file `cmsalice2bob.p7m` was created using 
	[`CMS_MakeEnvData`](#CMS_MakeEnvData).
	The output file should look like the following.	

```

Content-Type: application/pkcs7-mime;
        smime-type=enveloped-data;
        id="smime.p7m"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
        fileid="smime.p7m"

MIAGCSqGSIb3DQEHA6CAMIACAQAxgcAwgb0CAQAwJjASMRAwDgYDVQQDEwdDYXJs
UlNBAhBGNGvHgABWvBHTbi7NXXHQMA0GCSqGSIb3DQEBAQUABIGAFx80IYQbAX8+
7PIXJzUInDUydJv9tgogwzQY8KHwneD1Wcihc/Thi3QtSIQu4bnoPlSbGdF76SuE
Cajdnq5PDU34SnMywq8fyBxDM0ayUfYfMozZOhnM4mr9F4lF3zqtAhnukQF8b+Hv
cTgt4XHHrk2P5vHhdtaA4spSM9kDtpwwgAYJKoZIhvcNAQcBMBQGCCqGSIb3DQMH
BAh7TZ7TVakVU6CABCCNGoP9xsyKSFr1lFrffFky8Ym+efPbS4jx1ODxWzHa3wAA
AAAAAAAAAAA=

```

### See Also

[SMIME_Extract](#SMIME_Extract)

[[Contents](#topofpage)] [[Index](#index)]

<a id="TDEA_B64Mode"></a>TDEA_B64Mode
-------------------------------------

Encrypts or decrypts data
encoded in base64 
using a specified mode. The key and initialization vector
are required in base64.

### VBA/VB6 Syntax

`Public Declare Function TDEA_B64Mode Lib "diCrPKI.dll" 
(ByVal strOutput As String, ByVal strInput As String, ByVal strKey As String, 
ByVal fEncrypt As Long, ByVal strMode As String, ByVal strIV As String) As Long`

`nRet = TDEA_B64Mode(strOutput, strInput, strKey, fEncrypt, strMode, strIV)`

### C/C++ Syntax

`long __stdcall TDEA_B64Mode(char *szOutput, const char *szInput, const char *szKey, long fEncrypt, const char *szMode, const char *szIV);`

### Parameters

*szOutput*
:   [out] of sufficient length to receive the output.

*szInput*
:   [in] containing the input data in base64.

*szKey*
:   [in] containing the key in base64 format.

*fEncrypt*
:   [in] direction flag:
set as `ENCRYPT` (True) to encrypt or `DECRYPT` (False)
to decrypt.

*szMode*
:   [in] specifying the confidentiality mode:  

`"ECB"` for Electronic Codebook mode,  

`"CBC"` for Cipher Block Chaining mode,  

`"CFB"` for 64-bit Cipher Feedback mode,  

`"OFB"` for Output Feedback mode, or  

`"CTR"` for Counter mode.

*szIV*
:   [in] containing the initialization vector (IV), if required,
in base64 format.

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

[Tdea.Encrypt Method](#M_Tdea_Encrypt_StringStringModeStringEncodingBase) (String, String, Mode, String, EncodingBase)  

[Tdea.Decrypt Method](#M_Tdea_Decrypt_StringStringModeStringEncodingBase) (String, String, Mode, String, EncodingBase)  

### Remarks

For ECB and CBC modes, the input string *szInput* must represent an exact multiple of eight bytes when decoded
otherwise a "Data not a valid length" error will result.
The key string *szKey* must represent exactly 24 bytes when decoded.
The initialization vector
string *szIV* must represent exactly 8 bytes when decoded
 unless *szMode* is `ECB`, 
in which case *szIV* is ignored (use `""`).
Valid base64 characters are [A-Za-z0-9+/] with '=' used as a padding character.
The output string *szOutput* must be set up with at least the same
number of characters as the input string before calling.
The variables *szOutput* and *szInput* should be different.

### Example

Examples in base64 are pretty obscure to read. This is the same example from 
[`TDEA_HexMode`](#TDEA_HexMode)
using base64 strings instead.

```

Dim nRet As Long
Dim sHexCorrect As String
Dim sHexInput As String
Dim sHexKey As String
Dim sHexInitV As String
Dim sOutput As String
Dim sInput As String
Dim sKey As String
Dim sInitV As String
Dim bEncrypt As Boolean
Dim sCorrect As String

' Start with input in hex
sHexInput = "5468697320736F6D652073616D706520636F6E74656E742E0808080808080808"
'            T h i s _ s o m e _ s a m p e _ c o n t e n t . (padding 8 x 08)
sHexKey = "737C791F25EAD0E04629254352F7DC6291E5CB26917ADA32"
sHexInitV = "B36B6BFB6231084E"
sHexCorrect = "d76fd1178fbd02f84231f5c1d2a2f74a4159482964f675248254223daf9af8e4"

' Convert to base64
sInput = cnvB64StrFromBytes(cnvBytesFromHexStr(sHexInput))
sKey = cnvB64StrFromBytes(cnvBytesFromHexStr(sHexKey))
sInitV = cnvB64StrFromBytes(cnvBytesFromHexStr(sHexInitV))
sCorrect = cnvB64StrFromBytes(cnvBytesFromHexStr(sHexCorrect))

' Set sOutput to be same length as sInput
sOutput = String(Len(sInput), " ")

Debug.Print "KY=" & sKey
Debug.Print "PT=" & sInput
Debug.Print "IV=" & sInitV
nRet = TDEA_B64Mode(sOutput, sInput, sKey, ENCRYPT, "CBC", sInitV)
Debug.Print "CT=" & sOutput & nRet
Debug.Print "OK=" & sCorrect

sInput = sOutput
nRet = TDEA_B64Mode(sOutput, sInput, sKey, DECRYPT, "CBC", sInitV)
Debug.Print "P'=" & sOutput & nRet

```

### See Also

[TDEA_BytesMode](#TDEA_BytesMode)
[TDEA_HexMode](#TDEA_HexMode)

[[Contents](#topofpage)] [[Index](#index)]

<a id="TDEA_BytesMode"></a>TDEA_BytesMode
-----------------------------------------

Encrypts or decrypts an array of Bytes
in one step
using a specified mode.

### VBA/VB6 Syntax

`Public Declare Function TDEA_BytesMode Lib "diCrPKI.dll" 
(ByRef lpOutput As Byte, ByRef lpInput As Byte, ByVal nDataLen As Long, ByRef lpKey As Byte, 
ByVal fEncrypt As Long, ByVal strMode As String, ByRef lpIV As Byte) As Long`

`nRet = TDEA_BytesMode(lpOutput(0), lpInput(0), nDataLen,
        lpKey(0), fEncrypt, strMode, lpIV(0))  ' Note the "(0)" after the byte array parameters`

### C/C++ Syntax

`long __stdcall TDEA_BytesMode(unsigned char *lpOutput, const unsigned char *lpData, long nDataLen, const unsigned char *lpKey, long fEncrypt, const char *szMode, const unsigned char *lpIV);`

### Parameters

*lpOutput*
:   [out] array of sufficient length to receive the output.

*lpData*
:   [in] array containing the input data.

*nDataLen*
:   [in] equal to length of the input data in bytes.

*lpKey*
:   [in] array containing the key.

*fEncrypt*
:   [in] direction flag:
set as `ENCRYPT` (True) to encrypt or `DECRYPT` (False)
to decrypt.

*szMode*
:   [in] specifying the confidentiality mode:  

`"ECB"` for Electronic Codebook mode,  

`"CBC"` for Cipher Block Chaining mode,  

`"CFB"` for 64-bit Cipher Feedback mode,  

`"OFB"` for Output Feedback mode, or  

`"CTR"` for Counter mode.

*lpIV*
:   [in] array containing the
initialization vector (IV), or zero (0) for ECB mode.

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

[Tdea.Encrypt Method](#M_Tdea_Encrypt_ByteByteModeByte) (Byte[], Byte[], Mode, Byte[])  

[Tdea.Decrypt Method](#M_Tdea_Decrypt_ByteByteModeByte) (Byte[], Byte[], Mode, Byte[])  

### Remarks

For ECB and CBC modes, the input data *lpInput* *must* be a multiple of 8 bytes long 
otherwise a "Data not a valid length" error will result.
The key *lpKey* must be exactly 24 bytes long and the IV, if required, exactly 8 bytes long.
The output array *lpOutput* must be at least *nDataLen* bytes long.
*lpOutput* and *lpInput* may be the same.

### Example

```

Dim nRet As Long
Dim sOutput As String
Dim sInput As String
Dim sKey As String
Dim sHexIV As String
Dim sCorrect As String
Dim nKeyLen As Long
Dim nDataLen As Long
Dim nIVLen As Long
Dim aKey() As Byte
Dim aResult() As Byte
Dim aData() As Byte
Dim aInitV() As Byte

sKey = "0123456789abcdeffedcba987654321089abcdef01234567"
sHexIV = "1234567890abcdef"
sInput = "Now is the time for all "
sCorrect = "204011f986e35647199e47af391620c5bb9a5bcfc86db0bb"

' Convert hex strings to byte arrays
nKeyLen = Len(sKey) \ 2
ReDim aKey(nKeyLen)
Call CNV_BytesFromHexStr(aKey(0), nKeyLen, sKey)
nIVLen = Len(sHexIV) \ 2
ReDim aInitV(nIVLen)
Call CNV_BytesFromHexStr(aInitV(0), nIVLen, sHexIV)

' Convert string to byte array and dimension aResult array
aData() = StrConv(sInput, vbFromUnicode)
nDataLen = UBound(aData) + 1
ReDim aResult(nDataLen - 1)

Debug.Print "KY=" & cnvHexStrFromBytes(aKey)
Debug.Print "IV=" & cnvHexStrFromBytes(aInitV)
Debug.Print "PT=" & "[" & sInput & "]"
' Encrypt in one-off process
nRet = TDEA_BytesMode(aResult(0), aData(0), nDataLen, _
    aKey(0), ENCRYPT, "CBC", aInitV(0))
Debug.Print "CT=" & cnvHexStrFromBytes(aResult) & nRet
Debug.Print "OK=" & sCorrect

' Now decrypt back
nRet = TDEA_BytesMode(aData(0), aResult(0), nDataLen, _
    aKey(0), DECRYPT, "cbc", aInitV(0))
sOutput = StrConv(aData(), vbUnicode)
Debug.Print "P'=" & "[" & sOutput & "]" & nRet

```

This should result in output as follows:

```

KY=0123456789ABCDEFFEDCBA987654321089ABCDEF01234567
IV=1234567890ABCDEF
PT=[Now is the time for all ]
CT=204011F986E35647199E47AF391620C5BB9A5BCFC86DB0BB 0
OK=204011f986e35647199e47af391620c5bb9a5bcfc86db0bb
P'=[Now is the time for all ] 0

```

### See Also

[TDEA_HexMode](#TDEA_HexMode)
[TDEA_B64Mode](#TDEA_B64Mode)
[TDEA_File](#TDEA_File)

[[Contents](#topofpage)] [[Index](#index)]

<a id="TDEA_File"></a>TDEA_File
-------------------------------

Encrypts or decrypts a file
using a specified mode. The key and initialization vector
are passed as arrays of bytes. PKCS-5/7 padding is used.

### VBA/VB6 Syntax

`Public Declare Function TDEA_File Lib "diCrPKI.dll" 
(ByVal strFileOut As String, ByVal strFileIn As String, ByRef lpKey As Byte, 
ByVal fEncrypt As Long, ByVal strMode As String, ByRef lpInitV As Byte) As Long`

`nRet = TDEA_File(strFileOut, strFileIn, lpKey(0), fEncrypt, strMode, lpInitV(0))`

### C/C++ Syntax

`long __stdcall TDEA_File(const char *szFileOut, const char *szFileIn, const unsigned char *lpKey, long fEncrypt, const char *szMode, const unsigned char *lpIV);`

### Parameters

*szFileOut*
:   [in] with the full path name of the output
file to be created.

*szFileIn*
:   [in] with the full path name of the input file
to be processed.

*lpKey*
:   [in] array containing the key.

*fEncrypt*
:   [in] direction flag:
set as `ENCRYPT` (True) to encrypt or `DECRYPT` (False)
to decrypt.

*szMode*
:   [in] specifying the confidentiality mode:  

`"ECB"` for Electronic Codebook mode,  

`"CBC"` for Cipher Block Chaining mode,  

`"CFB"` for 64-bit Cipher Feedback mode,  

`"OFB"` for Output Feedback mode, or  

`"CTR"` for Counter mode.

*lpIV*
:   [in] array containing the initialization vector (IV),
or zero (0) for ECB mode.

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

[Tdea.FileEncrypt Method](#M_Tdea_FileEncrypt_StringStringByteModeByte) (String, String, Byte[], Mode, Byte[])  

[Tdea.FileDecrypt Method](#M_Tdea_FileDecrypt_StringStringByteModeByte) (String, String, Byte[], Mode, Byte[])  

### Remarks

The key array *abKey()*
must be exactly 16 bytes long.
The initialization vector *abInitV()*
must be exactly the block size of 16 bytes long, except for ECB mode, where it is ignored (use `0`).

The output file *szFileOut* will be overwritten without warning.
If there is an error, the output file will **not exist**.
The input and output files must **not** be the same.

In ECB and CBC modes, a padding string will be added or assumed according to the method outlined in Section 6.3 of
[[CMS](#CMS)], 
which is the same as the padding method in [[PKCS7](#PKCS7)] section 10.3 and [[PKCS5](#PKCS5)] section 6.1.1
and [[RFC1423](#RFC1423)] para 1.1.

### Example

```

    Const MY_PATH As String = ""
    Dim aKey() As Byte
    Dim strFileOut As String
    Dim strFileIn As String
    Dim strFileChk As String
    Dim nRet As Long

    ' Construct full path names to files
    strFileIn = MY_PATH & "hello.txt"
    strFileOut = MY_PATH & "hello.tdea.enc.dat"
    strFileChk = MY_PATH & "hello.tdea.chk.txt"

    ' Create the key as an array of bytes
    ' This creates an array of 24 bytes {&HFE, &HDC, ... &H10}
    aKey = cnvBytesFromHexStr("fedcba9876543210fedcba9876543210fedcba9876543210")

    ' Encrypt plaintext file to ciphertext
    ' Output file = 16-byte ciphertext file hello.enc
    nRet = TDEA_File(strFileOut, strFileIn, aKey(0), ENCRYPT, "ECB", 0)
    Debug.Print nRet

    ' Now decrypt it
    nRet = TDEA_File(strFileChk, strFileOut, aKey(0), DECRYPT, "ECB", 0)
    Debug.Print nRet

```

### See Also

[TDEA_BytesMode](#TDEA_BytesMode)

[[Contents](#topofpage)] [[Index](#index)]

<a id="TDEA_HexMode"></a>TDEA_HexMode
-------------------------------------

Encrypts or decrypts data
represented as a hexadecimal string
using a specified mode. The key and initialization vector
are represented as a hexadecimal string.

### VBA/VB6 Syntax

`Public Declare Function TDEA_HexMode Lib "diCrPKI.dll" 
(ByVal strOutput As String, ByVal strInput As String, ByVal strKey As String, 
ByVal fEncrypt As Long, ByVal strMode As String, ByVal strIV As String) As Long`

`nRet = TDEA_HexMode(strOutput, strInput, strKey, fEncrypt, strMode, strIV)`

### C/C++ Syntax

`long __stdcall TDEA_HexMode(char *szOutput, const char *szInput, const char *szKey, long fEncrypt, const char *szMode, const char *szIV);`

### Parameters

*szOutput*
:   [out] of sufficient length to receive the output.

*szInput*
:   [in] containing the input data in hex format.

*szKey*
:   [in] containing the key in hex format.

*fEncrypt*
:   [in] direction flag:
set as `ENCRYPT` (True) to encrypt or `DECRYPT` (False)
to decrypt.

*szMode*
:   [in] specifying the confidentiality mode:  

`"ECB"` for Electronic Codebook mode,  

`"CBC"` for Cipher Block Chaining mode,  

`"CFB"` for 64-bit Cipher Feedback mode,  

`"OFB"` for Output Feedback mode, or  

`"CTR"` for Counter mode.

*szIV*
:   [in] containing the initialization vector (IV), if required,
in hex format.

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

[Tdea.Encrypt Method](#M_Tdea_Encrypt_StringStringModeString) (String, String, Mode, String)  

[Tdea.Decrypt Method](#M_Tdea_Decrypt_StringStringModeString) (String, String, Mode, String)  

### Remarks

For ECB and CBC modes, the length of the input string *szInput* must be a multiple of 16 hex characters long
(i.e. representing a multiple of 8 bytes) otherwise an error will result.
The key string *szKey*
must be exactly 48 hex characters long (i.e. representing exactly 24 bytes/192 bits).
The initialization vector
string *szIV* must be exactly 16 hex characters long
(i.e. representing exactly the block size of 8 bytes) unless *szMode* is `ECB`, 
in which case *szIV* is ignored (use `""`).
Valid hexadecimal characters are [0-9A-Fa-f].
The output string *szOutput* must be set up with the same
number of characters as the input string before calling.
The variables *szOutput* and *szInput* should be different.

### Example

This example is from Section 8.1 of  [[SMIME-EX]](#SMIME-EX).

```

Dim nRet As Long
Dim sOutput As String
Dim sInput As String
Dim sKey As String
Dim sInitV As String
Dim sCorrect As String

sInput = "5468697320736F6D652073616D706520636F6E74656E742E0808080808080808"
'         T h i s _ s o m e _ s a m p e _ c o n t e n t . (padding 8 x 08)
sKey = "737C791F25EAD0E04629254352F7DC6291E5CB26917ADA32"
sInitV = "B36B6BFB6231084E"
sCorrect = "d76fd1178fbd02f84231f5c1d2a2f74a4159482964f675248254223daf9af8e4"
' Set sOutput to be same length as sInput
sOutput = String(Len(sInput), " ")

Debug.Print "KY=" & sKey
Debug.Print "PT=" & sInput
nRet = TDEA_HexMode(sOutput, sInput, sKey, ENCRYPT, "CBC", sInitV)
Debug.Print "CT=" & sOutput & nRet
Debug.Print "OK=" & sCorrect

sInput = sOutput
nRet = TDEA_HexMode(sOutput, sInput, sKey, DECRYPT, "CBC", sInitV)
Debug.Print "P'=" & sOutput & nRet

```

This should result in output as follows:

```

KY=737C791F25EAD0E04629254352F7DC6291E5CB26917ADA32
PT=5468697320736F6D652073616D706520636F6E74656E742E0808080808080808
CT=D76FD1178FBD02F84231F5C1D2A2F74A4159482964F675248254223DAF9AF8E4 0
OK=d76fd1178fbd02f84231f5c1d2a2f74a4159482964f675248254223daf9af8e4
P'=5468697320736F6D652073616D706520636F6E74656E742E0808080808080808 0

```

### See Also

[TDEA_BytesMode](#TDEA_BytesMode)
[TDEA_B64Mode](#TDEA_B64Mode)

[[Contents](#topofpage)] [[Index](#index)]

<a id="WIPE_Data"></a>WIPE_Data
-------------------------------

Zeroise data in memory.

### VBA/VB6 Syntax

`Public Declare Function WIPE_Data Lib "diCrPKI.dll" 
    (ByRef lpData As Byte, ByVal nBytes As Long) As Long`

Alternative aliases for VBA/VB6 users to deal with Byte and String types explicitly:  

`Public Declare Function WIPE_Bytes Lib "diCrPKI.dll" Alias "WIPE_Data" 
    (ByRef lpData As Byte, ByVal nBytes As Long) As Long  

Public Declare Function WIPE_String Lib "diCrPKI.dll" Alias "WIPE_Data" 
    (ByVal strData As String, ByVal nStrLen As Long) As Long`

`nRet = WIPE_Data(lpData(0), nBytes) ' Note the "(0)" after the byte array parameters`

VBA/VB6 aliases only:  

`nRet = WIPE_Bytes(lpData(0), nBytes)  

nRet = WIPE_String(strData, nStrLen)`

### C/C++ Syntax

`long __stdcall WIPE_Data(void *lpData, long nDataLen);`

### Parameters

*lpData*
:   [in,out] array to be cleared.

*nDataLen*
:   [in] number of bytes in array to be cleared.

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero  [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`wipeBytes`](#VB_wipeBytes) (ByRef lpToWipe() As Byte) As Byte()  
Public Function [`wipeString`](#VB_wipeString) (ByRef szToWipe As String) As String

### .NET Equivalent

[Wipe.Data Method](#M_Wipe_Data)  

[Wipe.String Method](#M_Wipe_String)  

### C++ (STL) Equivalent

static bool [dipki::Wipe::Data](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_wipe.html#a6d3d230ff058e62ad26ec96f5b44d5d5 "External link") (bvec_t &data)  

static bool [dipki::Wipe::String](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_wipe.html#a7f4bcf4a0356d51efe7788b360bab3d4 "External link") (std::string &s)

### Python Equivalent

static [Wipe.data](https://cryptosys.net/pki/pydocpki/class-stubs/Wipe.html#cryptosyspki.Wipe.data "External link")(data)

### Remarks

This function does not free any memory; it just zeroises it.

### Example (VBA core function)

```

Dim lpData() As Byte
lpData = ... ' n bytes of data 
nRet = WIPE_Data(lpData(0), n)

```

```

Dim strData As String
strData = "my deepest secrets"
nRet = WIPE_String(strData, Len(strData))
strData = ""

```

```

long pwdlen;
char password[256];
pwdlen = PWD_Prompt(password, sizeof(password)-1, "Test");
if (pwdlen >= 0)
  printf("Password entered=[%s]\n", password);
else
  printf("No password entered\n");
/* ... do something with password ... */
WIPE_Data(password, pwdlen);

```

### Examples (VBA wrapper function)

```

Dim strData As String
strData = "my deepest secrets"
strData = wipeString(strData)

```

```

Dim lpData() As Byte
lpData = cnvBytesFromHexStr("DEADBEEF")
Debug.Print "BEFORE: " & cnvHexStrFromBytes(lpData)
Call wipeBytes(lpData)
Debug.Print "AFTER: '" & cnvHexStrFromBytes(lpData) & "'"

```

### See Also

[[Contents](#topofpage)] [[Index](#index)]

<a id="WIPE_File"></a>WIPE_File
-------------------------------

Wipe and delete a file using secure 7-pass DOD standards.

### VBA/VB6 Syntax

`Public Declare Function WIPE_File Lib "diCrPKI.dll" 
    (ByVal strFileName As String, ByVal nOptions As Long) As Long`

`nRet = WIPE_File(strFileName, nOptions)`

### C/C++ Syntax

`long __stdcall WIPE_File(const char *szFileName, long nOptions);`

### Parameters

*szFileName*
:   [in] specifying the file to be deleted.

*nOptions*
:   [in] Option flags *[New in v12.0]*. Select one of:  

`PKI_WIPEFILE_DOD7` (0) to use DOD 7-pass (default)  

`PKI_WIPEFILE_SIMPLE` to overwrite with single pass of zero bytes (quicker but less secure).

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero  [error code](#errorcodes).

### .NET Equivalent

[Wipe.File Method](#M_Wipe_File)  

### C++ (STL) Equivalent

static bool [dipki::Wipe::File](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_wipe.html#a487b2823f03489759882f38617e15020 "External link") (const std::string fileName, Opts opts=Opts::Dod7Pass)

### Python Equivalent

static [Wipe.file](https://cryptosys.net/pki/pydocpki/class-stubs/Wipe.html#cryptosyspki.Wipe.file "External link")(filename, opts=Options.DEFAULT)

### Remarks

Wipes a file using the 7-pass DOD Standard according to [[NISPOM](#NISPOM)] before deleting.

### Example

```

nRet = WIPE_File("ToDelete.txt", 0)

```

### See Also

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_CertExpiresOn"></a>X509_CertExpiresOn
-------------------------------------------------

Returns the date and time an X.509 certificate expires. 

### VBA/VB6 Syntax

`Public Declare Function X509_CertExpiresOn Lib "diCrPKI.dll" 
    (ByVal strCertFile As String, ByVal strOutput As String, 
    ByVal nOutChars As Long, ByVal nOptions As Long) As Long`

`nRet = X509_CertExpiresOn(strCertFile, strOutput, nOutChars, nOptions)`

### C/C++ Syntax

`long __stdcall X509_CertExpiresOn(const char *szCertFile, char *szOutput, long nOutChars, long nOptions);`

### Parameters

*szCertFile*
:   [in] with the filename of the X.509 certificate
	(or [base64 representation](#base64forcert)).

*szOutput*
:   [out] to receive the time-date string.

*nOutChars*
:   [in] specifying the maximum length of the time-date string.

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

Returns the number of characters set in *szOutput*. 
If *nOutChars* is zero it returns the maximum number of characters required (currently 20, but
don't assume that for future releases).
C/C++ users should allocate one extra for the terminating NUL character.
If an error occurs, it returns a negative [error code](#errorcodes).

### .NET Equivalent

[X509.CertExpiresOn Method](#M_X509_CertExpiresOn)  

### Remarks

The time format is in accordance with [ISO 8601](#ISO8601) and will always be of the form YYYY-MM-DDThh:mm:ssZ.
The time is always given as GMT (Greenwich Mean Time, UTC, Zulu Time). 

### Example

```

Dim nRet As Long
Dim strCertName As String
Dim strDateTime As String * 32
 
strCertName = "AliceRSASignByCarl.cer"	' Change your dir to suit
nRet = X509_CertIssuedOn(strCertName, strDateTime, Len(strDateTime), 0)
Debug.Print "X509_CertIssuedOn returns " & nRet & " for " & strCertName & ": " & strDateTime
nRet = X509_CertExpiresOn(strCertName, strDateTime, Len(strDateTime), 0)
Debug.Print "X509_CertExpiresOn returns " & nRet & " for " & strCertName & ": " & strDateTime

```

Should result in (in all locales):

```

X509_CertIssuedOn returns 20 for AliceRSASignByCarl.cer: 
1999-09-19T01:08:47Z            
X509_CertExpiresOn returns 20 for AliceRSASignByCarl.cer: 
2039-12-31T23:59:59Z            

```

### See Also

[X509_CertIssuedOn](#X509_CertIssuedOn)
[X509_CertIsValidNow](#X509_CertIsValidNow)
[X509_QueryCert](#X509_QueryCert)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_CertIssuedOn"></a>X509_CertIssuedOn
-----------------------------------------------

Returns the date and time an X.509 certificate was issued.

### VBA/VB6 Syntax

`Public Declare Function X509_CertIssuedOn Lib "diCrPKI.dll" 
    (ByVal strCertFile As String, ByVal strOutput As String, 
    ByVal nOutChars As Long, ByVal nOptions As Long) As Long`

`nRet = X509_CertIssuedOn(strCertFile, strOutput, nOutChars, nOptions)`

### C/C++ Syntax

`long __stdcall X509_CertIssuedOn(const char *szCertFile, char *szOutput, long nOutChars, long nOptions);`

### Parameters

*szCertFile*
:   [in] with the filename of the X.509 certificate
	(or [base64 representation](#base64forcert)).

*szOutput*
:   [out] to receive the time-date string.

*nOutChars*
:   [in] specifying the maximum length of the time-date string.

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

Returns the number of characters set in *szOutput*. 
If *nOutChars* is zero it returns the maximum number of characters required (currently 20, but
don't assume that for future releases).
C/C++ users should allocate one extra for the terminating NUL character.
If an error occurs, it returns a negative [error code](#errorcodes).

### .NET Equivalent

[X509.CertIssuedOn Method](#M_X509_CertIssuedOn)  

### Remarks

The time format is in accordance with [ISO 8601](#ISO8601) and will always be of the form YYYY-MM-DDThh:mm:ssZ.
The time is always given as GMT (Greenwich Mean Time, UTC, Zulu Time). 

### Example

See [`X509_CertExpiresOn`](#X509_CertExpiresOn).

### See Also

[X509_CertExpiresOn](#X509_CertExpiresOn)
[X509_CertIsValidNow](#X509_CertIsValidNow)
[X509_QueryCert](#X509_QueryCert)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_CertIssuerName"></a>X509_CertIssuerName
---------------------------------------------------

Extracts issuer's distinguished name from X.509 certificate.

### VBA/VB6 Syntax

`Public Declare Function X509_CertIssuerName Lib "diCrPKI.dll" 
    (ByVal strCertFile As String, ByVal strOutput As String, 
    ByVal nOutChars As Long, ByVal strDelim As String, ByVal nOptions As Long) As Long`

`nRet = X509_CertIssuerName(strCertFile, strOutput, nOutChars, strDelim, nOptions)`

### C/C++ Syntax

`long __stdcall X509_CertIssuerName(const char *szCertFile, char *szOutput, long nOutChars, const char *szDelim, long nOptions);`

### Parameters

*szCertFile*
:   [in] with the filename of the X.509 certificate
	(or [base64 representation](#base64forcert)).

*szOutput*
:   [out] to receive the name string.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szDelim*
:   [in] specifying the character to use as a delimiter (default ";").

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_DEFAULT` (0) (default)  

`PKI_X509_LDAP` to output the [LDAP string representation](#ldapstring) as per RFC 4514  

`PKI_X509_LATIN1` to try and convert Unicode/UTF-8/T.61 attribute strings to Latin-1 (8-bit ASCII)

### Returns (VBA/C)

Returns the number of characters set in *szOutput*. 
If *nOutChars* is zero it returns the maximum number of characters required.
C/C++ users should allocate one extra for the terminating NUL character.
If an error occurs, it returns a negative [error code](#errorcodes).

The output using the `PKI_X509_LDAP` option is suitable as content for an `<X509IssuerName>`
node in an XML-DSIG document.

### .NET Equivalent

[X509.CertIssuerName Method](#M_X509_CertIssuerName)  

### Remarks

See the remarks for [`X509_CertSubjectName()`](#X509_CertSubjectName).

### Example

See [`X509_CertSubjectName`](#X509_CertSubjectName).

### See Also

[X509_CertIssuerName](#X509_CertSubjectName)
[X509_HashIssuerAndSN](#X509_HashIssuerAndSN)
[X509_QueryCert](#X509_QueryCert)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_CertIsValidNow"></a>X509_CertIsValidNow
---------------------------------------------------

Verifies that an X.509 certificate is currently valid. 

### VBA/VB6 Syntax

`Public Declare Function X509_CertIsValidNow Lib "diCrPKI.dll" 
    (ByVal strCertFile As String, ByVal nOptions As Long) As Long`

`nRet = X509_CertIsValidNow(strCertFile, nOptions)`

### C/C++ Syntax

`long __stdcall X509_CertIsValidNow(const char *szCertFile, long nOptions);`

### Parameters

*szCertFile*
:   [in] with the filename of the certificate
		(or [base64 representation](#base64forcert)).

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

Zero (0) if the certificate is valid at the current time.
If the certificate has expired or is not yet valid, the return value is 
`PKI_X509_EXPIRED`  (+16 = `EXPIRED_ERROR`);
otherwise it returns a *positive* [error code](#errorcodes).

### .NET Equivalent

[X509.CertIsValidNow Method](#M_X509_CertIsValidNow)  

### C++ (STL) Equivalent

static bool [dipki::X509::CertIsValidNow](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#ac6ef066faf9ca7d9c4e5b7d7d5a04973 "External link") (const std::string &certFile)

### Python Equivalent

static [X509.cert_is_valid_now](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.cert_is_valid_now "External link")(certfile)

### Remarks

Note that the return value for "success" is zero, not "true".  Uses the system clock.
The certificate may be in binary DER format or base64 PEM format.

*[Changed in v12.0]* If the certificate is otherwise of correct format but has expired or is not yet valid, this function returns `EXPIRED_ERROR` (16). 
Previous versions would return -1.

### Example

```

Dim nRet As Long
Dim strCertName As String
 
strCertName = "myca.cer"
nRet = X509_CertIsValidNow(strCertName, 0)
Debug.Print "X509_CertIsValidNow returns " & nRet & " for " & strCertName

```

### See Also

[X509_VerifyCert](#X509_VerifyCert)
[X509_ValidatePath](#X509_ValidatePath)
[X509_CertThumb](#X509_CertThumb)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_CertRequest"></a>X509_CertRequest
---------------------------------------------

Creates a PKCS #10 certificate signing request (CSR)
using the subject's private key file. 

### VBA/VB6 Syntax

`Public Declare Function X509_CertRequest Lib "diCrPKI.dll"
    (ByVal strReqFile As String, ByVal strPriKeyFile As String,
    ByVal strDistName As String, ByVal strExtensions As String,
    ByVal strPassword As String, ByVal nOptions As Long) As Long`

`nRet = X509_CertRequest(strReqFile, 
    strPriKeyFile, strDistName, strExtensions, strPassword, nOptions)`

### C/C++ Syntax

`long __stdcall X509_CertRequest(const char *szNewReqFile, const char *szPriKeyFile, const char *szDistName, const char *szExtensions, const char *szPassword, long nOptions);`

### Parameters

*szNewReqFile*
:   [in] Name of new certificate request file to be created.

*szPriKeyFile*
:   [in] Name of subject's private key file (encrypted or unencrypted) or a [PEM string](#pemstring) containing the key.

*szDistName*
:   [in]  Distinguished name string.
See [Specifying Distinguished Names](#distnames) for more details.

*szExtensions*
:   [in] (optional) Extensions: a list of attribute-value pairs separated by semicolons (;)
to be added to an `extensionRequest` element.
See [X.509 Extensions Parameter](#x509extensions).
*[New in v10.0]*.

*szPassword*
:   [in] Password for subject's encrypted private key file. Specify the empty string `""` if key not encrypted *[New in v12.0]*.

*nOptions*
:   [in] Option flags. 

Choose one signature algorithm from:  

`PKI_SIG_SHA1RSA` (0) to use `sha1WithRSAEncryption` (default - CAUTION)  

`PKI_SIG_SHA224RSA` to use `sha224WithRSAEncryption`  

`PKI_SIG_SHA256RSA` to use `sha256WithRSAEncryption` [minimum recommended]  

`PKI_SIG_SHA384RSA` to use `sha384WithRSAEncryption`  

`PKI_SIG_SHA512RSA` to use `sha512WithRSAEncryption`  

`PKI_SIG_MD5RSA` to use `md5WithRSAEncryption` [legacy, not recommended]  

`PKI_SIG_MD2RSA` to use `md2WithRSAEncryption` [legacy, definitely not recommended]  

`PKI_SIG_RSA_PSS_SHA1` to use `RSA-PSS-SHA1`  

`PKI_SIG_RSA_PSS_SHA224` to use `RSA-PSS-SHA224`  

`PKI_SIG_RSA_PSS_SHA256` to use `RSA-PSS-SHA256`  

`PKI_SIG_RSA_PSS_SHA384` to use `RSA-PSS-SHA384`  

`PKI_SIG_RSA_PSS_SHA512` to use `RSA-PSS-SHA512`  

`PKI_SIG_ECDSA_SHA1` to use `ecdsaWithSHA1`  

`PKI_SIG_ECDSA_SHA224` to use `ecdsaWithSHA224`  

`PKI_SIG_ECDSA_SHA256` to use `ecdsaWithSHA256`  

`PKI_SIG_ECDSA_SHA384` to use `ecdsaWithSHA384`  

`PKI_SIG_ECDSA_SHA512` to use `ecdsaWithSHA512`  

`PKI_SIG_ED25519` to use `Ed25519` *[New in v20.0]*  

`PKI_SIG_ED448` to use `Ed448` *[New in v22.0]*  

  

And add any combination of these:-
  

`PKI_X509_FORMAT_BIN` to create a BER-encoded binary file (default = base64 PEM format)  

`PKI_X509_REQ_KLUDGE` to create a request with the "kludge" that omits the 
strictly mandatory attributes completely (default = include attributes with zero-length field)  

`PKI_X509_UTF8` to encode the DN as `UTF8String` (default = PrintableString)  

  

Specialist options:-  

`PKI_PSS_SALTLEN_ZERO` to use a zero-length salt in an RSA-PSS signature.  

`PKI_SIG_DETERMINISTIC` to use the deterministic digital signature generation procedure of [[RFC6979](#RFC6979)] for an ECDSA signature.

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero  [error code](#errorcodes).

### .NET Equivalent

[X509.CertRequest Method](#M_X509_CertRequest)  

### C++ (STL) Equivalent

static int [dipki::X509::CertRequest](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#af0c4852b7eb96fe4be27dbb5eb738855 "External link") (const std::string &newFile, const std::string &priKeyFile, const std::string &password, const std::string distName, const std::string extns="", SigAlg sigAlg=SigAlg::Default, CsrOptions opts=CsrOptions::Default_CsrOpt)

### Python Equivalent

static [X509.cert_request](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.cert_request "External link")(newcsrfile, prikeyfile, password, distname, extns="", sigalg=0, opts=0)

### Remarks

The default output is a base64 PEM format CSR file ready for sending to the issuer of your choice.
Any existing file of the same name will be overwritten without warning.

### Example

This example will create a new certificate request with filename `myreq.p10.txt`.
for the subject with common name "myuser", etc.
The subject's encrypted private key is in the file `mykey.p8e` and has
the password "password". The certificate request will be signed using the subject's private key
using the default `sha1WithRSAEncryption` algorithm.

```

Dim nRet As Long
nRet = X509_CertRequest("myreq.p10.txt", "mykey.p8e", _
  "CN=myuser;O=Test Org;C=AU;L=Sydney;S=NSW", "", "password", 0)
If nRet <> 0 Then
  Debug.Print nRet & " " & pkiGetLastError()
Else
  Debug.Print "Success"
End If

```

This should produce an output file similar to:

```

-----BEGIN CERTIFICATE REQUEST-----
MIIBGjCBxQIBADBQMQ8wDQYDVQQDEwZteXVzZXIxETAPBgNVBAoTCFRlc3QgT3Jn
MQswCQYDVQQGEwJBVTEPMA0GA1UECBMGU3lkbmV5MQwwCgYDVQQHEwNOU1cwWjAN
BgkqhkiG9w0BAQEFAANJADBGAkEAvdci5sKarpPzljBVVxJfGEfBOvjxlgFYOg1x
xEEG9Xbilxgl3kTfIrA4KqNmGdEKPksbHXNuxXkwaaAld3bBHQIBA6ASMBAGCisG
AQQBgjcCAQ4xAjAAMA0GCSqGSIb3DQEBBQUAA0EAtqie6G31yRcwJljEDdbeYd+w
5FvLd631nL//JuISFv6fl9B30WtHQtI1wuryVYZ6fRWZPpu9jZjs5gsnKFtiUg==
-----END CERTIFICATE REQUEST-----

```

The next example duplicates the certificate request in Sections 3.1 to 3.3 of "Some Examples of the PKCS Standards"
[[PKCS-EX](#PKCS-EX)].
It uses the 508-bit private key to sign the request, which is stored in the file `rsa508.p8e`
with the password "password". The signature algorithm is `md2WithRSAEncryption`
and the output is in binary format. To reproduce this example requires the non-strict "kludge".
The output should exactly match the CertificationRequest value in section 3.2 of PKCS-EX.

```

Dim nRet As Long
nRet = X509_CertRequest("pkcs_ex_req.bin", "rsa508.p8e", _
  "C=US;O=Example Organization;CN=Test User 1", "", "password", _
  PKI_SIG_MD2RSA + PKI_X509_FORMAT_BIN + PKI_X509_REQ_KLUDGE)
If nRet <> 0 Then
  Debug.Print nRet & " " & pkiGetLastError()
Else
  Debug.Print "Success"
End If

```

The latter example is just to demonstrate the replication of an old but known test vector, not to demonstrate good practice. 

### See Also

[X509_MakeCert](#X509_MakeCert)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_CertSerialNumber"></a>X509_CertSerialNumber
-------------------------------------------------------

Returns the serial number of an X.509 certificate. 

### VBA/VB6 Syntax

`Public Declare Function X509_CertSerialNumber Lib "diCrPKI.dll" 
    (ByVal strCertFile As String, ByVal strOutput As String, 
    ByVal nOutChars As Long, ByVal nOptions As Long) As Long`

`nRet = X509_CertSerialNumber(strCertFile, strOutput, nOutChars, nOptions)`

### C/C++ Syntax

`long __stdcall X509_CertSerialNumber(const char *szCertFile, char *szOutput, long nOutChars, long nOptions);`

### Parameters

*szCertFile*
:   [in] with the filename of the X.509 certificate
	(or [base64 representation](#base64forcert)).

*szOutput*
:   [out] to receive the serial number.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*nOptions*
:   [in] option flags:   

`PKI_DEFAULT` (0) for default output in hexadecimal format 

`PKI_X509_DECIMAL` to output number in decimal format

### Returns (VBA/C)

Returns the number of characters set in *szOutput*. 
If *nOutChars* is zero it returns the maximum number of characters required.
C/C++ users should allocate one extra for the terminating NUL character.
If an error occurs, it returns a negative [error code](#errorcodes).

### .NET Equivalent

[X509.CertSerialNumber Method](#M_X509_CertSerialNumber)  

### Remarks

The certificate may be in binary DER format or base64 PEM format.

### Example

```

Dim nRet As Long
Dim strCertName As String
Dim strOutput As String * 64
 
strCertName = "BobRSASignByCarl.cer"	' Set dir to suit
nRet = X509_CertSerialNumber(strCertName, strOutput, Len(strOutput), 0)
Debug.Print "X509_CertSerialNumber returns " & nRet & " for " & strCertName & ": " & Left(strOutput, nRet)

```

Should result in

```

X509_CertSerialNumber returns 32 for BobRSASignByCarl.cer: 
46346bc7800056bc11d36e2ecd5d71d0                                

```

### See Also

[X509_CertIsValidNow](#X509_CertIsValidNow)
[X509_CertThumb](#X509_CertThumb)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_CertSubjectName"></a>X509_CertSubjectName
-----------------------------------------------------

Extracts subject's distinguished name from X.509 certificate.

### VBA/VB6 Syntax

`Public Declare Function X509_CertSubjectName Lib "diCrPKI.dll" 
    (ByVal strCertFile As String, ByVal strOutput As String, 
    ByVal nOutChars As Long, ByVal strDelim As String, ByVal nOptions As Long) As Long`

`nRet = X509_CertSubjectName(strCertFile, strOutput, nOutChars, strDelim, nOptions)`

### C/C++ Syntax

`long __stdcall X509_CertSubjectName(const char *szCertFile, char *szOutput, long nOutChars, const char *szDelim, long nOptions);`

### Parameters

*szCertFile*
:   [in] with the filename of the X.509 certificate
	(or [base64 representation](#base64forcert)).

*szOutput*
:   [out] to receive the name string.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*szDelim*
:   [in] specifying the character to use as a delimiter (default ";").

*nOptions*
:   [in] Option flags. 

`PKI_DEFAULT` (0) (default)  

`PKI_X509_LDAP` to output the [LDAP string representation](#ldapstring) as per RFC 4514  

`PKI_X509_LATIN1` to try and convert Unicode/UTF-8/T.61 attribute strings to Latin-1 (8-bit ASCII)

### Returns (VBA/C)

Returns the number of characters set in *szOutput*. 
If *nOutChars* is zero it returns the maximum number of characters required.
C/C++ users should allocate one extra for the terminating NUL character.
If an error occurs, it returns a negative [error code](#errorcodes).

### .NET Equivalent

[X509.CertSubjectName Method](#M_X509_CertSubjectName)  

### Remarks

The distinguished name will be returned in a string expressed 
in the same format described in [Distinguished Names](#distnames), e.g. `"C=AU;O=myorg;CN=Dave"`. 
Only the first character in *szDelim* is used. 
The default delimiter is a semi-colon (;) if an empty string or NULL is specified for *szDelim*.
If the attribute key is not in our set of [supported types](#dnsupportedtype),
the OID will be expressed in dot notation, e.g. `"2.5.4.4=My Surname"`.

If an attribute value is encoded in a multi-byte-character string format (such as UTF8String or BMPString), 
the value will be expressed as a hexadecimal-encoded string *[NB changed in v3.9]*  
preceded by the hash symbol (`'#'` U+0023) and small letter x (`'x'` U+0078), e.g.

```

"C=TW;O=E8 A1 8C E6 94 BF E9 99 A2" (v3.8 and earlier)
"C=TW;O=#xE8A18CE694BFE999A2" (v3.9 and later)

```

 
Use the `PKI_X509_LATIN1` option to return the string encoded in Latin-1, if possible, so it will display properly on systems that
cannot cope with UTF-8.

*[New in v3.9]* Use the `PKI_X509_LDAP` option to obtain the distinguished name in LDAP string form instead.
The examples above would be returned as `"CN=Dave,O=myorg,C=AU"` and 
`"O=\E8\A1\8C\E6\94\BF\E9\99\A2,C=TW"`, with commas as delimiters, the RDNs in reverse order, and non-printable-ASCII
characters escaped in hexadecimal form "\xx" as per [[RFC4514](#RFC4514)].
See [LDAP string representation](#ldapstring) for more details.
The *szDelim* parameter is ignored with the `PKI_X509_LDAP` option.

The output using the `PKI_X509_LDAP` option is suitable as content for an `<X509SubjectName>`
node in an XML-DSIG document.

### Example

```

Dim nRet As Long
Dim nLen As Long
Dim strCertName As String
Dim strOutput As String
 
strCertName = "dai.cer"
nLen = X509_CertIssuerName(strCertName, "", 0, ";", 0)
Debug.Print "X509_CertIssuerName returns " & nLen & " for " & strCertName
strOutput = String(nLen, " ")
nRet = X509_CertIssuerName(strCertName, strOutput, Len(strOutput), ";", 0)
Debug.Print "[" & strOutput & "]"

' Example outputting in LDAP format
nLen = X509_CertIssuerName(strCertName, "", 0, "", PKI_X509_LDAP)
Debug.Print "X509_CertIssuerName(LDAP) returns " & nLen & " for " & strCertName
strOutput = String(nLen, " ")
nRet = X509_CertIssuerName(strCertName, strOutput, Len(strOutput), "", PKI_X509_LDAP)
Debug.Print "[" & strOutput & "]"

nLen = X509_CertSubjectName(strCertName, "", 0, ";", 0)
Debug.Print "X509_CertSubjectName returns " & nLen & " for " & strCertName
strOutput = String(nLen, " ")
nRet = X509_CertSubjectName(strCertName, strOutput, Len(strOutput), ",", 0)
Debug.Print "[" & strOutput & "]"

' Example outputting in LDAP format
nLen = X509_CertSubjectName(strCertName, "", 0, "", PKI_X509_LDAP)
Debug.Print "X509_CertSubjectName(LDAP) returns " & nLen & " for " & strCertName
strOutput = String(nLen, " ")
nRet = X509_CertSubjectName(strCertName, strOutput, Len(strOutput), "", PKI_X509_LDAP)
Debug.Print "[" & strOutput & "]"

```

This example is for an old Thawte personal certificate. The output is as follows:

```

X509_CertIssuerName returns 100 for dai.cer
[C=ZA;ST=Western Cape;L=Cape Town;O=Thawte;OU=Certificate Services;CN=Personal Freemail RSA 2000.8.30]
X509_CertIssuerName(LDAP) returns 100 for dai.cer
[CN=Personal Freemail RSA 2000.8.30,OU=Certificate Services,O=Thawte,L=Cape Town,ST=Western Cape,C=ZA]
X509_CertSubjectName returns 76 for dai.cer
[SN=Ireland,G=David Alexander,CN=David Alexander Ireland,E=code@di-mgt.com.au]
X509_CertSubjectName(LDAP) returns 107 for dai.cer
[1.2.840.113549.1.9.1=code@di-mgt.com.au,CN=David Alexander Ireland,2.5.4.42=David Alexander,2.5.4.4=Ireland]

```

### See Also

[X509_CertIssuerName](#X509_CertIssuerName)
[X509_HashIssuerAndSN](#X509_HashIssuerAndSN)
[X509_QueryCert](#X509_QueryCert)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_CertThumb"></a>X509_CertThumb
-----------------------------------------

Calculates the thumbprint (message digest hash) of an X.509 certificate. 

### VBA/VB6 Syntax

`Public Declare Function X509_CertThumb Lib "diCrPKI.dll" 
    (ByVal strCertFile As String, ByVal strHexHash As String, 
    ByVal nHexHashLen As Long, ByVal nOptions As Long) As Long`

`nRet = X509_CertThumb(strCertFile, 
    strHexHash, nHexHashLen, nOptions)`

### C/C++ Syntax

`long __stdcall X509_CertThumb(const char *szCertFile, char *szOutput, long nOutChars, long nOptions);`

### Parameters

*szCertFile*
:   [in] with the filename of the X.509 certificate
	(or [base64 representation](#base64forcert)).

*szOutput*
:   [out] to receive the message digest.

*nOutChars*
:   [in] specifying the maximum length of the digest string.

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_HASH_SHA1` (0) to use the SHA-1 algorithm (default)  

`PKI_HASH_SHA224` to use the SHA-224 algorithm  

`PKI_HASH_SHA256` to use the SHA-256 algorithm  

`PKI_HASH_SHA384` to use the SHA-384 algorithm  

`PKI_HASH_SHA512` to use the SHA-512 algorithm  

`PKI_HASH_MD5` to use the MD5 algorithm

### Returns (VBA/C)

the number of digits set in the output string or a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`x509CertThumb`](#VB_x509CertThumb) (szCertFile As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[X509.CertThumb Method](#M_X509_CertThumb)  

### C++ (STL) Equivalent

static std::string [dipki::X509::CertThumb](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a42640b33c3c4c2745644b2c3f067ed21 "External link") (const std::string &certFile, HashAlg hashAlg=HashAlg::Sha1)

### Python Equivalent

static [X509.cert_thumb](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.cert_thumb "External link")(certfilename, hashalg=0)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The maximum length of the output string is `PKI_MAX_HASH_CHARS` (C/C++ users add one).
The default hash algorithm is SHA-1 and the result should
match the SHA-1 thumbprint shown in the Windows Certificate Viewer.

### Example (VBA core function)

These examples compute the SHA-1 message digest hash ("thumbprint") of Alice's certificate from 
S/MIME examples.

```

Dim nRet As Long
Dim strCertName As String
Dim strHexHash As String
 
strHexHash = String(PKI_SHA1_CHARS, " ")
strCertName = "AliceRSASignByCarl.cer"
nRet = X509_CertThumb(strCertName, strHexHash, Len(strHexHash), 0)
Debug.Print "X509_CertThumb returns " & nRet & " for " & strCertName
Debug.Print strHexHash

```

In C:

```

long lRet;
char *certname = "C:\\test\\AliceRSASignByCarl.cer";
char hexdigest[PKI_SHA1_CHARS+1]; /* NB one extra */

lRet = X509_CertThumb(certname, hexdigest, sizeof(hexdigest)-1, 0);
printf("X509_CertThumb returns %ld for %s\n", lRet, certname);
printf("%s\n", hexdigest);

```

Both of these should result in

```

X509_CertThumb returns 40 for AliceRSASignByCarl.cer
b30c48855055c2e64ce3196492d4b83831a6b3cb

```

### Example (VBA wrapper function)

```

Dim strCertString As String
strCertString = x509ReadStringFromFile("AliceRSASignByCarl.cer")
Debug.Print strCertString
Debug.Print "CertThumb=" & x509CertThumb(strCertString)
strCertString = x509ReadCertStringFromP7Chain("alice_bob_carl_certs.p7c", 3)
Debug.Print strCertString
Debug.Print "CertThumb=" & x509CertThumb(strCertString)
Debug.Print "HashIssuerAndSN=" & x509HashIssuerAndSN(strCertString, PKI_HASH_SHA256)

```

### See Also

[X509_CertIsValidNow](#X509_CertIsValidNow)
[X509_VerifyCert](#X509_VerifyCert)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_CheckCertInCRL"></a>X509_CheckCertInCRL
---------------------------------------------------

Checks whether an X.509 certificate has been revoked in a Certificate Revocation List (CRL).

### VBA/VB6 Syntax

`Public Declare Function X509_CheckCertInCRL Lib "diCrPKI.dll" (ByVal strCertFile As String, ByVal strCrlFile As String, ByVal strCRLIssuerCert As String, ByVal strDate As String, ByVal nOptions As Long) As Long`

`nRet = X509_CheckCertInCRL(strCertFile, strCrlFile, strCRLIssuerCert, 
    strDate, nOptions)`

### C/C++ Syntax

`long __stdcall X509_CheckCertInCRL(const char *szCertFile, const char *szCrlFile, const char *szCRLIssuerCert, const char *szDate, long nOptions);`

### Parameters

*szCertFile*
:   [in] with name of X.509 certificate to be checked 
	(or [base64 representation](#base64forcert)).

*szCrlFile*
:   [in] with name of CRL file.

*szCRLIssuerCert*
:   [in] (optional) with name of X.509 certificate file for the entity that issued the CRL
	(or [base64 representation](#base64forcert)).

*szDate*
:   [in] (optional) with date in 
[ISO date format](#iso8601datetime) (e.g. `2009-12-31T12:59:59Z`)
on or after you wish to check for revocation. 
Leave empty `""` for any date. The time *must* be in GMT (UTC, Zulu time).

*nOptions*
:   [in] Option flags. Not used. Specify zero.

### Returns (VBA/C)

Zero (0) if the certificate is not in the CRL (i.e has not been revoked by that particular CRL). 
If the certificate has been revoked it returns `PKI_X509_REVOKED` (+42=`REVOCATION_ERROR`);
otherwise a *negative* [error code](#errorcodes).

### .NET Equivalent

[X509.CheckCertInCRL Method](#M_X509_CheckCertInCRL)  

### Python Equivalent

static [X509.cert_is_revoked](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.cert_is_revoked "External link")(certfile, crlfile, crl_issuercert="", isodate="")

### Remarks

The optional *szDate* parameter allows you to check whether a certificate was revoked only after the given date-time, 
which **must** be in GMT (UTC). If the optional *szCRLIssuerCert* is specified,
the signature of the CRL will be checked against the key in the issuer's certificate and a `SIGNATURE_ERROR` will result
if the signature is invalid.

You can directly verify the signature in the CRL file using the [X509_VerifyCert()](#X509_VerifyCert) function.

*[Changed in v12.0]* If the certificate is otherwise of correct format but has been revoked, this function returns `REVOCATION_ERROR` (42). 
Previous versions would return +1.

### Example

```

Dim nRet As Long
Dim strCrlFile As String
Dim strCertFile As String
Dim strDate As String

' Use test CRL and certs from RFC3280
strCrlFile = "rfc3280bis_CRL.crl"
' This cert has not been revoked.
strCertFile = "rfc3280bis_cert1.cer"
Debug.Print "CrlFile=" & strCrlFile
Debug.Print "CertFile=" & strCertFile
nRet = X509_CheckCertInCRL(strCertFile, strCrlFile, "", "", 0)
Debug.Print "X509_CheckCertInCRL returns " & nRet
If nRet = PKI_X509_REVOKED Then
  Debug.Print "CERT HAS BEEN REVOKED"
ElseIf nRet = 0 Then
  Debug.Print "Cert has not been revoked"
Else
  Debug.Print "ERROR: " & pkiErrorLookup(nRet) & ": " & pkiGetLastError()
End If

' This cert has been revoked.
strCertFile = "rfc3280bis_cert2.cer"
Debug.Print "CrlFile=" & strCrlFile
Debug.Print "CertFile=" & strCertFile
nRet = X509_CheckCertInCRL(strCertFile, strCrlFile, "", "", 0)
Debug.Print "X509_CheckCertInCRL returns " & nRet
If nRet = PKI_X509_REVOKED Then
  Debug.Print "CERT HAS BEEN REVOKED"
ElseIf nRet = 0 Then
  Debug.Print "Cert has not been revoked"
Else
  Debug.Print "ERROR: " & pkiErrorLookup(nRet) & ": " & pkiGetLastError()
End If

' But the same cert was not revoked as at 15:00 GMT on 19 November 2004
strCertFile = "rfc3280bis_cert2.cer"
strDate = "2004-11-19T15:00Z"
Debug.Print "CrlFile=" & strCrlFile
Debug.Print "CertFile=" & strCertFile
Debug.Print "Date=" & strDate
nRet = X509_CheckCertInCRL(strCertFile, strCrlFile, "", strDate, 0)
Debug.Print "X509_CheckCertInCRL(" & strDate & ") returns " & nRet
If nRet = PKI_X509_REVOKED Then
  Debug.Print "CERT HAS BEEN REVOKED"
ElseIf nRet = 0 Then
  Debug.Print "Cert has not been revoked"
Else
  Debug.Print "ERROR: " & pkiErrorLookup(nRet) & ": " & pkiGetLastError()
End If

```

This code should produce the following output

```

CrlFile=rfc3280bis_CRL.crl
CertFile=rfc3280bis_cert1.cer
X509_CheckCertInCRL returns 0
Cert has not been revoked
CrlFile=rfc3280bis_CRL.crl
CertFile=rfc3280bis_cert2.cer
X509_CheckCertInCRL returns 1
CERT HAS BEEN REVOKED
CrlFile=rfc3280bis_CRL.crl
CertFile=rfc3280bis_cert2.cer
Date=2004-11-19T15:00Z
X509_CheckCertInCRL(2004-11-19T15:00Z) returns 0
Cert has not been revoked

```

### See Also

[X509_MakeCRL](#X509_MakeCRL)
[X509_VerifyCert](#X509_VerifyCert)
[X509_CertIsValidNow](#X509_CertIsValidNow)
[X509_ValidatePath](#X509_ValidatePath)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_GetCertCountInP7Chain"></a>X509_GetCertCountInP7Chain
-----------------------------------------------------------------

Return number of certificates in a PKCS-7 "certs-only" certificate chain file. 

### VBA/VB6 Syntax

`Public Declare Function X509_GetCertCountInP7Chain Lib "diCrPKI.dll" (ByVal strP7cFile As String, ByVal nOptions As Long) As Long`

`nRet = X509_GetCertCountInP7Chain(strP7cFile, nOptions) As Long`

### C/C++ Syntax

`long __stdcall X509_GetCertCountInP7Chain(const char *szP7cFile, long nOptions);`

### Parameters

*szP7cFile*
:   [in] filename of the PKCS-7 "certs-only" file, or a string containing its [PEM textual representation](#pemstring).

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

Number of X.509 certificates found or a negative [error code](#errorcodes).

### .NET Equivalent

[X509.GetCertCountInP7Chain Method](#M_X509_GetCertCountInP7Chain)  

### C++ (STL) Equivalent

static int [dipki::X509::GetCertCountInP7Chain](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#ab39028867279fae0db82bd281caedbc1 "External link") (const std::string &inputFile)

### Python Equivalent

static [X509.get_cert_count_from_p7](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.get_cert_count_from_p7 "External link")(p7file)

### Remarks

This function will also work with CMS signed data objects, too.

### Example

```

nCerts = X509_GetCertCountInP7Chain("certs.p7c", 0)

```

will return the number of certificates found in the file `certs.p7c`.

### See Also

[X509_GetCertFromP7Chain](#X509_GetCertFromP7Chain)
[X509_ReadCertStringFromP7Chain](#X509_ReadCertStringFromP7Chain)
[CMS_QuerySigData](#CMS_QuerySigData)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_GetCertFromP7Chain"></a>X509_GetCertFromP7Chain
-----------------------------------------------------------

Extracts an X.509 certificate from a PKCS-7 "certs-only" certificate chain file
(typically saved with extension `.p7c` or `.p7b`), 
saving the output directly as a new file.

### VBA/VB6 Syntax

`Public Declare Function X509_GetCertFromP7Chain Lib "diCrPKI.dll" 
    (ByVal strOutputFile As String, ByVal strP7cFile As String, ByVal nIndex As Long, ByVal nOptions As Long) As Long`

`nRet = X509_GetCertFromP7Chain(strOutputFile, strP7cFile, nIndex, nOptions) As Long`

### C/C++ Syntax

`long __stdcall X509_GetCertFromP7Chain(const char *szNewCertFile, const char *szP7cFile, long nIndex, long nOptions);`

### Parameters

*szNewCertFile*
:   [in] filename of the output file to be created.

*szP7cFile*
:   [in] filename of the PKCS-7 "certs-only" file, or a string containing its [PEM textual representation](#pemstring).

*nIndex*
:   [in] specifying which certificate (1,2,...) in the chain to extract, 
	or 0 (deprecated) to return the count of certificates in the set.

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful and *nIndex* is greater than zero, it returns the number of bytes written to the output file,
which may be zero if no certificate could be found at the given index.
If an error occurred, it returns a negative [error code](#errorcodes).

### .NET Equivalent

[X509.GetCertFromP7Chain Method](#M_X509_GetCertFromP7Chain)  

### C++ (STL) Equivalent

static bool [dipki::X509::GetCertFromP7Chain](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a08efea2f2eb7412bdbc0c47c9af25341 "External link") (const std::string &outputFile, const std::string &inputFile, int index)

### Python Equivalent

static [X509.get_cert_from_p7](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.get_cert_from_p7 "External link")(outfile, p7file, index=1)

### Remarks

If *nIndex* is specified as a number greater than zero, the *nIndex*'th 
certificate found in the list, if any, 
will be extracted and saved directly as a DER-encoded X.509 certificate file.
This function will also extract certificates from CMS signed data objects, too.

*[New in v12.2]* To find the number of certificates in the chain, use [X509_GetCertCountInP7Chain](#X509_GetCertCountInP7Chain).
The old (deprecated) way to find the count of certificates was to set *nIndex* to zero. 

### Example

```

nBytes = X509_GetCertFromP7Chain("cert2.cer", "certs.p7c", 2, 0)

```

will extract the second certificate in `certs.p7c` 
and create a new X.509 certificate file called `cert2.cer`
containing `nBytes` bytes.

The following example shows how to extract all the certificates from a PKCS-7 CertList file

```

Dim nRet As Long
Dim strListFile As String
Dim strCertFile As String
Dim nCerts As Long
Dim iCert As Long

strListFile = "bob.p7b"
' How many certificates?  - NB new function in [v12.2]
nCerts = X509_GetCertCountInP7Chain(strListFile, 0)
Debug.Print "X509_GetCertCountInP7Chain returns " & nCerts & " for " & strListFile
' Enumerate through them all
If nCerts > 0 Then
    For iCert = 1 To nCerts
        strCertFile = "bobcert" & iCert & ".cer"
        nRet = X509_GetCertFromP7Chain(strCertFile, strListFile, iCert, 0)
        Debug.Print "X509_GetCertFromP7Chain(" & iCert & ") returns " _
            & nRet & "->" & strCertFile
    Next
End If

```

This should result in output as follows:

```

X509_GetCertCountInP7Chain() returns 2 for bob.p7b
X509_GetCertFromP7Chain(1) returns 555->bobcert1.cer
X509_GetCertFromP7Chain(2) returns 495->bobcert2.cer

```

where, in this example, the file `bob.p7b` contains two X.509 certificates 
of size 555 and 495 bytes respectively.

### See Also

[X509_ReadCertStringFromP7Chain](#X509_ReadCertStringFromP7Chain)
[X509_GetCertCountInP7Chain](#X509_GetCertCountInP7Chain)
[CMS_QuerySigData](#CMS_QuerySigData)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_GetCertFromPFX"></a>X509_GetCertFromPFX
---------------------------------------------------

Extracts an X.509 certificate from a PKCS-12 PFX/.p12 file, saving the output
directly as a new file.

### VBA/VB6 Syntax

`Public Declare Function X509_GetCertFromPFX Lib "diCrPKI.dll" 
    (ByVal strOutputFile As String, ByVal strPfxFile As String, 
    ByVal strPassword As String, ByVal nOptions As Long) As Long`

`nRet = X509_GetCertFromPFX(strOutputFile, strPfxFile, 
   	strPassword, nOptions) As Long`

### C/C++ Syntax

`long __stdcall X509_GetCertFromPFX(const char *szNewCertFile, const char *szPfxFile, const char *szPassword, long nOptions);`

### Parameters

*szNewCertFile*
:   [in] specifying the filename of the output file to be created.

*szPfxFile*
:   [in] containing the PFX filename

*szPassword*
:   [in] containing password or `""` if certificate is not encrypted

*nOptions*
:   [in] option flags:   

`PKI_DEFAULT` (0) to export a single DER-encoded X.509 certificate.  

`PKI_PFX_P7CHAIN` to output all certificates in a PKCS7 certificate chain file (`.p7b` or `.p7c`).

### Returns (VBA/C)

If successful, it returns the number of bytes written to the output file;
otherwise it returns a negative [error code](#errorcodes).

### .NET Equivalent

[X509.GetCertFromPFX Method](#M_X509_GetCertFromPFX)  

[X509.GetP7ChainFromPFX Method](#M_X509_GetP7ChainFromPFX)  

### C++ (STL) Equivalent

static bool [dipki::X509::GetCertFromPFX](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a203c6c2df25242677aed1b245d945bfa "External link") (const std::string &outputFile, const std::string &inputFile, const std::string &password)

static [X509.get_p7chain_from_pfx](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.get_p7chain_from_pfx "External link")(outfile, pfxfile, password)

### Python Equivalent

`static [X509.get_cert_from_pfx](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.get_cert_from_pfx "External link")(outfile, pfxfile, password)`

static [X509.get_p7chain_from_pfx](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.get_p7chain_from_pfx "External link")(outfile, pfxfile, password)

### Remarks

The default behaviour is to extract one certificate from the PFX file and save directly
as a DER-encoded X.509 certificate file.
Any existing file of the same name will be overwritten without warning.
It will attempt to find a matching certificate for any private key, otherwise it will save
the first `pkcs-12-certBag` found in the PFX file containing a 
`x509Certificate`. 

Both unencrypted certificates and certificates encrypted with the weak 40-bit encryption used by "default"
in Microsoft and OpenSSL PKCS-12 files are supported, but not any other encryption algorithm.

If no certificate can be found the function will return a negative `NO_DATA_ERROR` error code.

The `PKI_PFX_P7CHAIN` option will output all X.509 certificates found into a single PKCS#7 certificate chain file.
The correct MIME-designated file extension for such a file is `.p7c`, but for historical reasons
Microsoft use `.p7b` instead.

### Example

```

nChars = X509_GetCertFromPFX("mycert.cer", "mypkcs12file.pfx", "password", 0)

```

will extract an X.509 certificate from the PKCS-12 file `mypkcs12file.pfx`
with password "password",
and save it as the new DER-encoded certificate file `mycert.cer`.
The variable *nChars* will contain the size in bytes of the new file it created,
or a negative error code.

### See Also

[X509_ReadCertStringFromPFX](#X509_ReadCertStringFromPFX)
[PFX_VerifySig](#PFX_VerifySig)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_HashIssuerAndSN"></a>X509_HashIssuerAndSN
-----------------------------------------------------

Returns the message digest hash of the PKCS
#7 issuerAndSerialNumber value
of an X.509 certificate in hexadecimal format. 

### VBA/VB6 Syntax

`Public Declare Function X509_HashIssuerAndSN Lib "diCrPKI.dll" 
    (ByVal strCertFile As String, ByVal strOutput As String, 
    ByVal nOutChars As Long, ByVal nOptions As Long) As Long`

`nRet = X509_HashIssuerAndSN(strCertFile, strOutput, nOutChars, nOptions)`

### C/C++ Syntax

`long __stdcall X509_HashIssuerAndSN(const char *szCertFile, char *szOutput, long nOutChars, long nOptions);`

### Parameters

*szCertFile*
:   [in] with the filename of the X.509 certificate
	(or [base64 representation](#base64forcert)).

*szOutput*
:   [out] to receive the hash digest.

*nOutChars*
:   [in] specifying the maximum number of characters to be received.

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_HASH_SHA1` (0) to use the SHA-1 algorithm (default)  

`PKI_HASH_SHA224` to use the SHA-224 algorithm  

`PKI_HASH_SHA256` to use the SHA-256 algorithm  

`PKI_HASH_SHA384` to use the SHA-384 algorithm  

`PKI_HASH_SHA512` to use the SHA-512 algorithm  

`PKI_HASH_MD5` to use the MD5 algorithm

### Returns (VBA/C)

Returns the number of characters set in *szOutput*. 
If *nOutChars* is zero it returns the maximum number of characters required.
C/C++ users should allocate one extra for the terminating NUL character.
If an error occurs, it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`x509HashIssuerAndSN`](#VB_x509HashIssuerAndSN) (szCertFile As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[X509.HashIssuerAndSN Method](#M_X509_HashIssuerAndSN)  

### C++ (STL) Equivalent

static std::string [dipki::X509::HashIssuerAndSN](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#aab9ad8e8fa8aadf6df0c37c8a3ea89e1 "External link") (const std::string &certFile, HashAlg hashAlg=HashAlg::Sha1)

### Python Equivalent

static [X509.cert_hashissuersn](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.cert_hashissuersn "External link")(certfilename, hashalg=0)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The certificate may be in binary BER format or base64 PEM format.

### Example (VBA core function)

```

    Dim nRet As Long
    Dim strCertName As String
    Dim strOutput As String * PKI_MAX_HASH_CHARS
     
    strCertName = "BobRSASignByCarl.cer"	' Set dir to suit
    nRet = X509_HashIssuerAndSN(strCertName, strOutput, Len(strOutput), 0)
    Debug.Print "X509_HashIssuerAndSN returns " & nRet & " for " & strCertName & ": " & Left(strOutput, nRet)

```

Should result in

```

X509_HashIssuerAndSN returns 40 for BobRSASignByCarl.cer: 
483538bca32adeb3134fe9f74d1ae74cc9ed2e9e

```

### Example (VBA wrapper function)

```

Dim strCertString As String
strCertString = x509ReadStringFromFile("AliceRSASignByCarl.cer")
Debug.Print strCertString
Debug.Print "CertThumb=" & x509CertThumb(strCertString)
strCertString = x509ReadCertStringFromP7Chain("alice_bob_carl_certs.p7c", 3)
Debug.Print strCertString
Debug.Print "CertThumb=" & x509CertThumb(strCertString)
Debug.Print "HashIssuerAndSN=" & x509HashIssuerAndSN(strCertString, PKI_HASH_SHA256)

```

### See Also

[X509_CertIsValidNow](#X509_CertIsValidNow)
[X509_CertThumb](#X509_CertThumb)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_KeyUsageFlags"></a>X509_KeyUsageFlags
-------------------------------------------------

Returns a bitfield containing the keyUsage flags for an X.509 certificate. 

### VBA/VB6 Syntax

`Public Declare Function X509_KeyUsageFlags Lib "diCrPKI.dll" (ByVal strCertFile As String) As Long`

`nRet = X509_KeyUsageFlags(strCertFile)`

### C/C++ Syntax

`long __stdcall X509_KeyUsageFlags(const char *szCertFile);`

### Parameters

*szCertFile*
:   [in] with the filename of the X.509 certificate
	(or [base64 representation](#base64forcert)).

### Returns (VBA/C)

If successful, it returns a positive integer containing the keyUsage flags; or 0 if no keyUsage flags are set; otherwise it returns a negative [error code](#errorcodes).

### .NET Equivalent

[X509.KeyUsageFlags Method](#M_X509_KeyUsageFlags)  

### Python Equivalent

static [X509.key_usage_flags](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.key_usage_flags "External link")(certfile)

### Remarks

The certificate may be in binary BER format or base64 PEM format. The presence of a key usage flag can be ascertained by
AND'ing the result with the bitfield value for each flag.

```

digitalSignature 0x0001
nonRepudiation   0x0002
keyEncipherment  0x0004
dataEncipherment 0x0008
keyAgreement     0x0010
keyCertSign      0x0020
cRLSign          0x0040
encipherOnly     0x0080
decipherOnly     0x0100

```

These values are defined as `PKI_X509_KEYUSAGE_DIGITALSIGNATURE`, etc.

### Example

This shows how to find and display the key usage flags for a given certificate.

```

Dim nRet As Long
Dim strCertName As String
strCertName = "CarlRSASelf.cer"
nRet = X509_KeyUsageFlags(strCertName)
' Show the result as a hex number
Debug.Print "keyUsage flags are (0x" & Hex(nRet) & "):"
' Check all the keyUsage flags in turn
If (nRet And PKI_X509_KEYUSAGE_DIGITALSIGNATURE) <> 0 Then Debug.Print "digitalSignature"
If (nRet And PKI_X509_KEYUSAGE_NONREPUDIATION) <> 0 Then Debug.Print "nonRepudiation"
If (nRet And PKI_X509_KEYUSAGE_KEYENCIPHERMENT) <> 0 Then Debug.Print "keyEncipherment"
If (nRet And PKI_X509_KEYUSAGE_DATAENCIPHERMENT) <> 0 Then Debug.Print "dataEncipherment"
If (nRet And PKI_X509_KEYUSAGE_KEYAGREEMENT) <> 0 Then Debug.Print "keyAgreement"
If (nRet And PKI_X509_KEYUSAGE_KEYCERTSIGN) <> 0 Then Debug.Print "keyCertSign"
If (nRet And PKI_X509_KEYUSAGE_CRLSIGN) <> 0 Then Debug.Print "cRLSign"
If (nRet And PKI_X509_KEYUSAGE_ENCIPHERONLY) <> 0 Then Debug.Print "encipherOnly"
If (nRet And PKI_X509_KEYUSAGE_DECIPHERONLY) <> 0 Then Debug.Print "decipherOnly"

' Alternatively, use X509_QueryCert to find these values as a string directly
Debug.Print "Use X509_QueryCert..."
Dim strOutput As String
Dim strQuery As String
Dim nChars As Long
strQuery = "keyUsageString"
nChars = X509_QueryCert("", 0, strCertName, strQuery, 0)
If nChars < 0 Then Exit Sub  ' ERROR
strOutput = String(nChars, " ")
nChars = X509_QueryCert(strOutput, Len(strOutput), strCertName, strQuery, 0)
Debug.Print "X509_QueryCert('" & strQuery & "')=" & strOutput

```

For the S/MIME test file `CarlRSASelf.cer`, this displays

```

keyUsage flags are (0x61):
digitalSignature
keyCertSign
cRLSign
Use X509_QueryCert...
X509_QueryCert('keyUsageString')=digitalSignature,keyCertSign,cRLSign

```

### See Also

[X509_QueryCert](#X509_QueryCert)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_MakeCert"></a>X509_MakeCert
---------------------------------------

Creates an X.509 certificate using subject's public key and issuer's private key files.

### VBA/VB6 Syntax

`Public Declare Function X509_MakeCert Lib "diCrPKI.dll" 
    (ByVal strNewCertFile As String, ByVal strIssuerCertFile As String, 
    ByVal strSubjectPubKeyFile As String, ByVal strIssuerPriKeyFile As String, 
    ByVal nCertNum As Long, ByVal nYearsValid As Long, 
    ByVal strDistName As String, ByVal strExtensions As String, 
    ByVal KeyUsageFlags As Long, 
    ByVal strPassword As String, ByVal nOptions As Long) As Long`

`nRet = X509_MakeCert(strNewCertFile, strIssuerCertFile, 
    strSubjectPubKeyFile, strIssuerPriKeyFile, nCertNum, nYearsValid, 
    strDistName, strExtensions, KeyUsageFlags, strPassword, nOptions)`

### C/C++ Syntax

`long __stdcall X509_MakeCert(const char *szNewCertFile, const char *szIssuerCertFile, const char *szSubjectPubKeyFile, const char *szIssuerPriKeyFile, long nCertNum, long nYearsValid, const char *szDistName, const char *szExtensions, long nKeyUsageFlags, const char *szPassword, long nOptions);`

### Parameters

*szNewCertFile*
:   [in] Name of new certificate file to be created.

*szIssuerCertFile*
:   [in] Name of issuer's X.509 certificate file
	(or its [base64 representation](#base64forcert) or as a [PEM string](#pemstring)).

*szSubjectPubKeyFile*
:   [in] Name of subject's public key file or a [PEM string](#pemstring) containing the key, or a valid internal key string.

*szIssuerPriKeyFile*
:   [in] Name of issuer's private key file (encrypted or unencrypted) or a [PEM string](#pemstring) containing the key, or a valid internal key string.

*nCertNum*
:   [in] Serial number for new certificate. Ignored if `serialNumber` is set in *szExtensions*.

*nYearsValid*
:   [in] Number of years certificate is to be valid from current date and hour (can be changed with *szExtensions*).

*szDistName*
:   [in] Distinguished name string. 
See [Specifying Distinguished Names](#distnames) for more details.

*szExtensions*
:   [in] Extensions: a list of attribute-value pairs separated by semicolons (;). 
See [X.509 Extensions Parameter](#x509extensions). Specify `""` or `NULL` to ignore.

*nKeyUsageFlags*

:   [in] Bit flags to set Key Usage extension:

| Option | To set |
| --- | --- |
| `PKI_X509_KEYUSAGE_DIGITALSIGNATURE` | `digitalSignature` |
| `PKI_X509_KEYUSAGE_NONREPUDIATION` | `nonRepudiation` |
| `PKI_X509_KEYUSAGE_KEYENCIPHERMENT` | `keyEncipherment` |
| `PKI_X509_KEYUSAGE_DATAENCIPHERMENT` | `dataEncipherment` |
| `PKI_X509_KEYUSAGE_KEYAGREEMENT` | `keyAgreement` |
| `PKI_X509_KEYUSAGE_KEYCERTSIGN` | `keyCertSign` |
| `PKI_X509_KEYUSAGE_CRLSIGN` | `cRLSign` |
| `PKI_X509_KEYUSAGE_ENCIPHERONLY` | `encipherOnly` |
| `PKI_X509_KEYUSAGE_DECIPHERONLY` | `decipherOnly` |

Add to combine options. Specify zero to omit Key Usage extension.

*szPassword*
:   [in] Password for issuer's encrypted private key file. Specify the empty string `""` if key not encrypted *[New in v12.0]*.

*nOptions*
:   [in] Option flags. 
Choose one signature algorithm from:  

`PKI_SIG_SHA1RSA` (0) to use `sha1WithRSAEncryption` (default - CAUTION)  

`PKI_SIG_SHA224RSA` to use `sha224WithRSAEncryption`  

`PKI_SIG_SHA256RSA` to use `sha256WithRSAEncryption` [minimum recommended]  

`PKI_SIG_SHA384RSA` to use `sha384WithRSAEncryption`  

`PKI_SIG_SHA512RSA` to use `sha512WithRSAEncryption`  

`PKI_SIG_MD5RSA` to use `md5WithRSAEncryption` [legacy, not recommended]  

`PKI_SIG_MD2RSA` to use `md2WithRSAEncryption` [legacy, definitely not recommended]  

`PKI_SIG_RSA_PSS_SHA1` to use `RSA-PSS-SHA1`  

`PKI_SIG_RSA_PSS_SHA224` to use `RSA-PSS-SHA224`  

`PKI_SIG_RSA_PSS_SHA256` to use `RSA-PSS-SHA256`  

`PKI_SIG_RSA_PSS_SHA384` to use `RSA-PSS-SHA384`  

`PKI_SIG_RSA_PSS_SHA512` to use `RSA-PSS-SHA512`  

`PKI_SIG_ECDSA_SHA1` to use `ecdsaWithSHA1`  

`PKI_SIG_ECDSA_SHA224` to use `ecdsaWithSHA224`  

`PKI_SIG_ECDSA_SHA256` to use `ecdsaWithSHA256`  

`PKI_SIG_ECDSA_SHA384` to use `ecdsaWithSHA384`  

`PKI_SIG_ECDSA_SHA512` to use `ecdsaWithSHA512`  

`PKI_SIG_ED25519` to use `Ed25519` *[New in v20.0]*  

`PKI_SIG_ED448` to use `Ed448` *[New in v22.0]*  

  

And add any combination of these:-  

`PKI_X509_VERSION1` to generate a Version 1 certificate, i.e. no extensions (default = Version 3).  

`PKI_X509_CA_TRUE` to set the `basicConstraints` subject type to be a CA (default = End Entity)  

`PKI_X509_NO_BASIC` to disable the `basicConstraints` extension (default = include)  

`PKI_X509_UTF8` to encode the subject's DN fields as `UTF8String` (default = PrintableString)  

`PKI_X509_FORMAT_PEM` to save the certificate in PEM format (default = DER-encoded binary)  

`PKI_X509_AUTHKEYID` to add the issuer's KeyIdentifier, if present, as an AuthorityKeyIdentifer (default = do not add)  

  

Specialist options:-  

`PKI_PSS_SALTLEN_ZERO` to use a zero-length salt in an RSA-PSS signature.  

`PKI_SIG_DETERMINISTIC` to use the deterministic digital signature generation procedure of [[RFC6979](#RFC6979)] for an ECDSA signature.

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero  [error code](#errorcodes).

### .NET Equivalent

[X509.MakeCert Method](#M_X509_MakeCert)  

### C++ (STL) Equivalent

static int [dipki::X509::MakeCert](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#abc55dc55d87795a5eec2c6a2754d57ec "External link") (const std::string &newCertFile, const std::string &issuerCert, const std::string &subjectPubKeyFile, const std::string &issuerPriKeyFile, const std::string &password, int certNum, int yearsValid, const std::string distName, const std::string extns="", KeyUsageOptions keyUsageOptions=KeyUsageOptions::NoKeyUsageOption, SigAlg sigAlg=SigAlg::Default, CertOptions opts=CertOptions::Default_CertOpt)

### Python Equivalent

static [X509.make_cert](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.make_cert "External link")(newcertfile, issuercert, subject_pubkeyfile, issuer_prikeyfile, password, certnum=0, yearsvalid=0, distname="", extns="", keyusage=KeyUsageFlags.NONE, sigalg=0, opts=0)

### Remarks

At least one valid attribute for the subject's distinguished name (DN) must be included. 
A version 1 certificate created using the `PKI_X509_VERSION1` flag will, by definition, exclude any version 3 extensions.

If the `PKI_X509_UTF8` flag is set, 
each attribute of the subject's DN will be encoded as a `UTF8String`.
Otherwise the default encoding will be `PrintableString` or, if a non-printable character is specified,
then as either `IA5String` or `T61String` - see [Specifying Distinguished Names](#distnames) for more details. 
The encoding of the issuer's DN will be exactly as in the issuer's certficate.

If the `PKI_X509_AUTHKEYID` flag is set then an `authorityKeyIdentifer` extension will 
be set *if* there is a corresponding `subjectKeyIdentifer` in the issuer's certificate.
Otherwise no such extension will be set.

The default validity period is from one minute ago by the system clock for a period of a whole number of years
set by the *nYearsValid* parameter. This time will always have the seconds set to 01.
A different validity period can be set using the `notBefore` and `notAfter` attributes
in the *szExtensions* parameter (see [X509 Extensions Parameter](#x509extensions)).

The serial number can be set to be an integer in the range 1 to 2,147,483,647 using the *nCertNum* parameter,
or (once you have used these up!) it can be set to a larger value, perhaps a random large integer represented by a hexadecimal string, using the `serialNumber` attribute
in the *szExtensions* parameter (see [X509 Extensions Parameter](#x509extensions)). 

As an alternative, you can create a new X.509 certificate using a PKCS-10 certificate signing request (CSR) file.
Pass the name of the CSR file in the *szSubjectPubKeyFile* parameter and set the *szDistName*	empty `""`.
The empty distinguished name parameter is a flag that a CSR file is being used. See the example below.

*[New in v12.0]* Added support for unencrypted private key files for *szIssuerPriKeyFile* as well as encrypted ones.
Specify `szPassword=""` to flag an unencrypted key.

*[New in v12.0]* Added support for RSA-PSS and ECDSA signatures.
Both the signing key and the subject's public key must be either both RSA keys for the RSA options, or both EC keys for the ECDSA signature options.
The MGF hash function for RSA-PSS signatures in an X.509 certificate is *always* the same as the signature hash function.
The signing key must be long enough to include the specified digest value and other encoding bytes. 
For example, a 1024-bit RSA key is too short to sign using RSA-PSS-SHA512 (see [RSA signature and encryption schemes](#rsaschemes)).
Not all signature options provided may be accepted by other applications.
Note also that both these signature schemes are probabilistic and each new signature contains randomly generated salt values,
so you won't reproduce the same certificate even with identical inputs.
Use the specialist options `PKI_PSS_SALTLEN_ZERO` and `PKI_SIG_DETERMINISTIC` with RSA-PSS and ECDSA, respectively, to force 
a deterministic (fixed) result.

*[New in v12.3]*
Added ability to specify an empty subjectName, to set extKeyUsage extension purposes in the [X.509 Extensions Parameter](#x509extensions), 
and mark an [arbitrary extension](#arbitraryx509extn) as critical.
Setting `szDistName = "$"` will create an X.509 document with an empty subjectName. 
At least one field for a subject alternative name extension (`altSubjectName`) must be specified and the extension will automatically be marked critical.

```

char *dn = "$";
char *extns = "iPAddress=192.168.15.1;extKeyUsage=serverAuth,clientAuth,emailProtection,critical;";

```

*[New in v20.5]*
Added ability to pass an internal key string for the subject's public key and signer's private key.

### Example

```

Dim nRet As Long
Dim strNewCertFile As String
Dim strIssuerCert As String
Dim strSubjectPubKeyFile As String
Dim strIssuerPriKeyFile As String
Dim strPassword As String
Dim nCertNum As Long
Dim nYearsValid As Long
Dim strDistName As String
Dim strEmail As String
strNewCertFile = "myuser.cer"
strIssuerCert = "myca.cer"
strSubjectPubKeyFile = "mykey.pub"
strIssuerPriKeyFile = "myca.p8e"
strPassword = "password"  '!!
nCertNum = &H101
nYearsValid = 4
strDistName = "CN=My User;O=Test Org;OU=Unit;C=AU;L=My Town;S=State;E=myuser@testorg.com"
strEmail = "myuser@testorg.com"

nRet = X509_MakeCert(strNewCertFile, strIssuerCert, strSubjectPubKeyFile, strIssuerPriKeyFile, _
    nCertNum, nYearsValid, strDistName, strEmail, 0, strPassword, 0)
If nRet <> 0 Then
    Debug.Print nRet & " " & pkiErrorLookup(nRet)
Else
    Debug.Print "Success, created X.509 cert " & strNewCertFile
End If

```

The above example will create a new X.509 certificate with filename `myuser.cer`.
The certificate will be issued by "myca" with serial number 257 (0x101) 
for the subject with common name "My User", etc.
It will be valid from one minute ago today for 4 years.
The subject's public key in file `mykey.pub` will be included and it will be signed
by the issuer with certificate `myca.cer` and private key in file `myca.p8e`.

The next example in C uses the advanced *szExtensions* parameter to re-create exactly Alice's certificate
from the S/MIME examples [[SMIME-EX](#SMIME-EX)].

```

char *certname;
char *issuercert = "CarlRSASelf.cer";
char *pubfile = "AlicePubRSA.pub";
char *epkfile = "CarlPrivRSASign.p8e";
char *password = "password";

char *certfile = "AliceRSA-dup.cer";
char *dn = "CN=AliceRSA";
char *extns = "rfc822name=AliceRSA@example.com;"
	"serialNumber=46346BC7800056BC11D36E2EC410B3B0;"
	"subjectKeyIdentifier=77D2B4D1B74C8A8AA3CE459DCEEC3CA03AE3FF50;"
	"notBefore=1999-09-19T01:08:47;"
	"notAfter=2039-12-31;"
	;
long keyUsage = PKI_X509_KEYUSAGE_DIGITALSIGNATURE + PKI_X509_KEYUSAGE_NONREPUDIATION;
long lRet;
char digest[PKI_SHA1_CHARS+1];

/* Make an end-user cert identical to RFC4134 AliceRSASignByCarl.cer */
certname = certfile;
lRet = X509_MakeCert(certname, issuercert, pubfile, epkfile, 
	0, 99, dn, extns, keyUsage, password, PKI_X509_AUTHKEYID);
assert(lRet == 0);
printf("Created end-user X.509 certificate '%s'\n", certname);

/* Check its SHA-1 thumbprint */
X509_CertThumb(certname, digest, sizeof(digest)-1, 0);
printf("SHA-1 Thumb=%s\n", digest);

```

This should give the output

```

Created end-user X.509 certificate 'AliceRSA-dup.cer'
SHA-1 Thumb=b30c48855055c2e64ce3196492d4b83831a6b3cb

```

### See Also

[X509_MakeCertSelf](#X509_MakeCertSelf)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_MakeCertSelf"></a>X509_MakeCertSelf
-----------------------------------------------

Creates a self-signed X.509 certificate.

### VBA/VB6 Syntax

`Public Declare Function X509_MakeCertSelf Lib "diCrPKI.dll" 
    (ByVal strNewCertFile As String, ByVal strPriKeyFile As String, 
    ByVal nCertNum As Long, ByVal nYearsValid As Long, 
    ByVal strDistName As String, ByVal strExtensions As String, 
    ByVal KeyUsageFlags As Long, 
    ByVal strPassword As String, ByVal nOptions As Long) As Long`

`nRet = X509_MakeCertSelf(strNewCertFile, strPriKeyFile, 
    nCertNum, nYearsValid, 
    strDistName, strExtensions, KeyUsageFlags, strPassword, nOptions)`

### C/C++ Syntax

`long __stdcall X509_MakeCertSelf(const char *szNewCertFile, const char *szPriKeyFile, long nCertNum, long nYearsValid, const char *szDistName, const char *szExtensions, long nKeyUsageFlags, const char *szPassword, long nOptions);`

### Parameters

*szNewCertFile*
:   [in] Name of new certificate file to be created.

*szPriKeyFile*
:   [in] Name of issuer's private key file (encrypted or unencrypted) or a [PEM string](#pemstring) containing the key, or a valid internal key string.

*nCertNum*
:   [in] Serial number for new certificate. Ignored if `serialNumber` is set in *szExtensions*.

*nYearsValid*
:   [in] Number of years certificate is to be valid starting at current date and hour (can be changed with *szExtensions*).

*szDistName*
:   [in] Distinguished name string (required). 
See [Specifying Distinguished Names](#distnames) for more details.

*szExtensions*
:   [in] Extensions: optional list of attribute-value pairs separated by semicolons (;). 
See [X.509 Extensions Parameter](#x509extensions). Specify `""` or `NULL` to ignore.

*nKeyUsageFlags*
:   [in] Flags to set Key Usage extensions:
	

| `PKI_X509_KEYUSAGE_DIGITALSIGNATURE` | to set `digitalSignature` |
| --- | --- |
| `PKI_X509_KEYUSAGE_NONREPUDIATION` | to set `nonRepudiation` |
| `PKI_X509_KEYUSAGE_KEYENCIPHERMENT` | to set `keyEncipherment` |
| `PKI_X509_KEYUSAGE_DATAENCIPHERMENT` | to set `dataEncipherment` |
| `PKI_X509_KEYUSAGE_KEYAGREEMENT` | to set `keyAgreement` |
| `PKI_X509_KEYUSAGE_KEYCERTSIGN` | to set `keyCertSign` |
| `PKI_X509_KEYUSAGE_CRLSIGN` | to set `cRLSign` |
| `PKI_X509_KEYUSAGE_ENCIPHERONLY` | to set `encipherOnly` |
| `PKI_X509_KEYUSAGE_DECIPHERONLY` | to set `decipherOnly` |

Add to combine options. Specify zero to omit Key Usage extension.

*szPassword*
:   [in] containing password for Issuer's encrypted private key file. Specify the empty string `""` if key not encrypted *[New in v12.0]*.

*nOptions*
:   [in] Option flags. 
Choose one signature algorithm from:  

`PKI_SIG_SHA1RSA` (0) to use `sha1WithRSAEncryption` (default - CAUTION)  

`PKI_SIG_SHA224RSA` to use `sha224WithRSAEncryption`  

`PKI_SIG_SHA256RSA` to use `sha256WithRSAEncryption` [minimum recommended]  

`PKI_SIG_SHA384RSA` to use `sha384WithRSAEncryption`  

`PKI_SIG_SHA512RSA` to use `sha512WithRSAEncryption`  

`PKI_SIG_MD5RSA` to use `md5WithRSAEncryption` [legacy, not recommended]  

`PKI_SIG_MD2RSA` to use `md2WithRSAEncryption` [legacy, definitely not recommended]  

`PKI_SIG_RSA_PSS_SHA1` to use `RSA-PSS-SHA1`  

`PKI_SIG_RSA_PSS_SHA224` to use `RSA-PSS-SHA224`  

`PKI_SIG_RSA_PSS_SHA256` to use `RSA-PSS-SHA256`  

`PKI_SIG_RSA_PSS_SHA384` to use `RSA-PSS-SHA384`  

`PKI_SIG_RSA_PSS_SHA512` to use `RSA-PSS-SHA512`  

`PKI_SIG_ECDSA_SHA1` to use `ecdsaWithSHA1`  

`PKI_SIG_ECDSA_SHA224` to use `ecdsaWithSHA224`  

`PKI_SIG_ECDSA_SHA256` to use `ecdsaWithSHA256`  

`PKI_SIG_ECDSA_SHA384` to use `ecdsaWithSHA384`  

`PKI_SIG_ECDSA_SHA512` to use `ecdsaWithSHA512`  

`PKI_SIG_ED25519` to use `Ed25519` *[New in v20.0]*  

`PKI_SIG_ED448` to use `Ed448` *[New in v22.0]*  

  

And add any combination of these:-  

`PKI_X509_VERSION1` to generate a Version 1 certificate, i.e. no extensions (default = Version 3).  

`PKI_X509_CA_TRUE` to set the `basicConstraints` subject type to be a CA (default = End Entity)  

`PKI_X509_NO_BASIC` to disable the `basicConstraints` extension (default = include)  

`PKI_X509_UTF8` to encode the subject's DN fields as `UTF8String` (default = PrintableString)  

`PKI_X509_FORMAT_PEM` to save the certificate in PEM format (default = DER-encoded binary)  

  

Specialist options:-  

`PKI_PSS_SALTLEN_ZERO` to use a zero-length salt in an RSA-PSS signature.  

`PKI_SIG_DETERMINISTIC` to use the deterministic digital signature generation procedure of [[RFC6979](#RFC6979)] for an ECDSA signature.

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero  [error code](#errorcodes).

### .NET Equivalent

[X509.MakeCertSelf Method](#M_X509_MakeCertSelf)  

### C++ (STL) Equivalent

static int [dipki::X509::MakeCertSelf](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a8f3dcd821cf4e2e614f9b859ffc8e675 "External link") (const std::string &newCertFile, const std::string &priKeyFile, const std::string &password, int certNum, int yearsValid, const std::string distName, const std::string extns="", KeyUsageOptions keyUsageOptions=KeyUsageOptions::NoKeyUsageOption, SigAlg sigAlg=SigAlg::Default, CertOptions opts=CertOptions::Default_CertOpt)

### Python Equivalent

static [X509.make_cert_self](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.make_cert_self "External link")(newcertfile, prikeyfile, password, certnum, yearsvalid, distname, extns="", keyusage=0, sigalg=0, opts=0)

### Remarks

See the remarks for [`X509_MakeCert()`](#X509_MakeCert).
A self-signed certificate has the same Issuer and Subject distinguished name. 
Add the `PKI_X509_UTF8` flag to encode the distinguished names in UTF-8.
The `BasicConstraints` subject type will always be a CA for a version 3 self-signed certificate, unless
explicitly excluded with the `PKI_X509_NO_BASIC` flag.

### Example

```

Dim nRet As Long
Dim nKeyUsage As Long

nKeyUsage = PKI_X509_KEYUSAGE_DIGITALSIGNATURE + _
    PKI_X509_KEYUSAGE_KEYCERTSIGN + PKI_X509_KEYUSAGE_CRLSIGN
nRet = X509_MakeCertSelf("myca.cer", "myca.p8e", 99, 10, _
    "CN=My CA;O=Test Org;OU=Certificate Services", _
    "", nKeyUsage, "password", 0)
If nRet <> 0 Then
    Debug.Print nRet & " " & pkiGetLastError()
Else
    Debug.Print "Success"
End If

```

The above example will create a new self-signed X.509 certificate with filename `myca.cer`.
The serial number will be 99.
It will be valid from today for 10 years.
The issuer's encrypted private key is in the file `myca.p8e` and has
the password "password". The new certificate will be signed using the private key
using the default `sha1WithRSAEncryption` algorithm.

The second example below shows how to specify a distinguished name using UTF-8-encoded CJK characters.
The `PKI_X509_UTF8` flag *must* be used in this case.

```

Dim nRet As Long
Dim nKeyUsage As Long
Dim strDN As String

' Specify DN using chinese characters in UTF-8
' CN=da wei (U+5927, U+536B)
' C=zhong guo (U+4E2D, U+56FD)
strDN = "CN=#xE5A4A7E58DAB;C=#xe4b8ade59bbd"
nKeyUsage = PKI_X509_KEYUSAGE_DIGITALSIGNATURE + PKI_X509_KEYUSAGE_KEYCERTSIGN + PKI_X509_KEYUSAGE_CRLSIGN
nRet = X509_MakeCertSelf("myca-chinadavid.cer", "myca.p8e", _
    &H888, 4, strDN, "", nKeyUsage, "password", PKI_X509_UTF8)
If nRet <> 0 Then
    Debug.Print nRet & " " & pkiGetLastError()
Else
    Debug.Print "Success"
End If

```

### See Also

[X509_MakeCert](#X509_MakeCert)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_MakeCRL"></a>X509_MakeCRL
-------------------------------------

Creates an X.509 Certificate Revocation List (CRL).

### VBA/VB6 Syntax

`Public Declare Function X509_MakeCRL Lib "diCrPKI.dll" (ByVal strCrlFile As String, ByVal strIssuerCert As String, ByVal strIssuerKeyFile As String, ByVal strPassword As String, ByVal strRevokedCertList As String, ByVal strExtensions As String, ByVal nOptions As Long) As Long`

`nRet = X509_MakeCRL(strCrlFile, strIssuerCert, 
    strIssuerKeyFile, strPassword, strRevokedCertList, strExtensions, nOptions)`

### C/C++ Syntax

`long __stdcall X509_MakeCRL(const char *szCrlFile, const char *szIssuerCert, const char *szIssuerKeyFile, const char *szPassword, const char *szRevokedCertList, const char *szExtensions, long nOptions);`

### Parameters

*szCrlFile*
:   [in] with name of new CRL file to be created.

*szIssuerCert*
:   [in] with name of issuer's X.509 certificate file
	(or [base64 representation](#base64forcert)).

*szIssuerKeyFile*
:   [in] with name of issuer's encrypted private key file.

*szPassword*
:   [in] containing password for issuer's encrypted private key file.

*szRevokedCertList*
:   [in] with list of revoked certificates in format 
`serialNumber,revocationDate; ...`
or the empty string `""` for no revoked certificates. See the Remarks section below for more details.

*szExtensions*
:   [in] (optional) containing 
one or more attribute-value pairs separated by semicolons (`;`).
Valid attribute-value pairs are:

* `thisUpdate`=<iso-date-string>
* `nextUpdate`=<iso-date-string>

*nOptions*
:   [in] Option flags. 
Choose one signature algorithm from:  

`PKI_SIG_SHA1RSA` (0) to use `sha1WithRSAEncryption` (default - CAUTION)  

`PKI_SIG_SHA224RSA` to use `sha224WithRSAEncryption`  

`PKI_SIG_SHA256RSA` to use `sha256WithRSAEncryption` [minimum recommended]  

`PKI_SIG_SHA384RSA` to use `sha384WithRSAEncryption`  

`PKI_SIG_SHA512RSA` to use `sha512WithRSAEncryption`  

`PKI_SIG_MD5RSA` to use `md5WithRSAEncryption` [legacy, not recommended]  

`PKI_SIG_MD2RSA` to use `md2WithRSAEncryption` [legacy, definitely not recommended]  

`PKI_SIG_RSA_PSS_SHA1` to use `RSA-PSS-SHA1`  

`PKI_SIG_RSA_PSS_SHA224` to use `RSA-PSS-SHA224`  

`PKI_SIG_RSA_PSS_SHA256` to use `RSA-PSS-SHA256`  

`PKI_SIG_RSA_PSS_SHA384` to use `RSA-PSS-SHA384`  

`PKI_SIG_RSA_PSS_SHA512` to use `RSA-PSS-SHA512`  

`PKI_SIG_ECDSA_SHA1` to use `ecdsaWithSHA1`  

`PKI_SIG_ECDSA_SHA224` to use `ecdsaWithSHA224`  

`PKI_SIG_ECDSA_SHA256` to use `ecdsaWithSHA256`  

`PKI_SIG_ECDSA_SHA384` to use `ecdsaWithSHA384`  

`PKI_SIG_ECDSA_SHA512` to use `ecdsaWithSHA512`  

`PKI_SIG_ED25519` to use `Ed25519` *[New in v20.0]*  

`PKI_SIG_ED448` to use `Ed448` *[New in v22.0]*  

  

And add any combination of these:-  

`PKI_X509_FORMAT_PEM` to save the certificate in PEM format (default = DER-encoded binary)  

  

Specialist options:-  

`PKI_PSS_SALTLEN_ZERO` to use a zero-length salt in an RSA-PSS signature.  

`PKI_SIG_DETERMINISTIC` to use the deterministic digital signature generation procedure of [[RFC6979](#RFC6979)] for an ECDSA signature.

### Returns (VBA/C)

If successful, the return value is zero;
otherwise it returns a nonzero  [error code](#errorcodes).

### .NET Equivalent

[X509.MakeCRL Method](#M_X509_MakeCRL)  

### C++ (STL) Equivalent

static int [dipki::X509::MakeCRL](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a8c1e71c90536e86f8f45a1f22af57d05 "External link") (const std::string &newFile, const std::string &issuerCert, const std::string &priKeyFile, const std::string &password, const std::string revokedCertList, const std::string extns="", SigAlg sigAlg=SigAlg::Default, CrlOptions opts=CrlOptions::Default_CrlOpt)

### Python Equivalent

static [X509.make_crl](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.make_crl "External link")(newcrlfile, issuercert, prikeyfile, password, revokedcertlist="", extns="", sigalg=0, opts=0)

### Remarks

This function creates a version 1 CRL file with no extensions or cRLReason's. 
The parameter *szRevokedCertList* must be in the form

```

serialNumber,revocationDate;serialNumber,revocationDate; ...

```

The serialNumber must either be a positive decimal number (e.g. `123`) or the number in hex format preceded by `"#x"`
(e.g. `"#x0102deadbeef"`). 
The revocation date must be in [ISO date format](#iso8601datetime) 
(e.g. `2009-12-31` or `2009-12-31T12:59:59Z`).

By default, the `lastUpdate` time in the CRL is set to the time given by the system clock, and
`nextUpdate` time is left empty.
You can specify your own times using the `lastUpdate` and `nextUpdate` attributes
in the *szExtensions* parameter.
Times, if specified, must be in [ISO 8601 format](#iso8601datetime) and are always interpreted as GMT times whether or not you add a "Z".

### Example

```

Dim nRet As Long
Dim strCrlFile As String
Dim strIssuerFile As String
Dim strKeyFile As String
Dim strPassword As String
Dim strCertList As String
Dim strExtension As String
' Create a new CRL dated with the current system time
strCrlFile = "CarlsNew.crl"
strIssuerFile = "CarlRSASelf.cer"
strKeyFile = "CarlPrivRSASign.p8e"
' CAUTION: DO NOT HARD-CODE REAL PASSWORDS!
strPassword = "password"
strCertList = "1,2007-12-31; 2, 2009-12-31T12:59:59Z; 66000,2066-01-01; #x0102deadbeef,2010-02-28T01:01:59"
nRet = X509_MakeCRL(strCrlFile, strIssuerFile, strKeyFile, strPassword, strCertList, "", 0)
Debug.Print "X509_MakeCRL returns " & nRet & " (expected 0)"
If (nRet = 0) Then
  Debug.Print "SUCCESS: New CRL file '" & strCrlFile & "' created."
Else
  Debug.Print "ERROR: " & pkiErrorLookup(nRet) & ": " & pkiGetLastError()
End If
' Create another CRL using specified times (NB these are GMT times, not local)
strExtension = "thisUpdate=2010-04-01T12:00;nextUpdate=2010-05-01"
strCrlFile = "Carl_20100401.crl"
nRet = X509_MakeCRL(strCrlFile, strIssuerFile, strKeyFile, strPassword, strCertList, strExtension, 0)
Debug.Print "X509_MakeCRL returns " & nRet & " (expected 0)"
If (nRet = 0) Then
  Debug.Print "SUCCESS: New CRL file '" & strCrlFile & "' created."
Else
  Debug.Print "ERROR: " & pkiErrorLookup(nRet) & ": " & pkiGetLastError()
End If

```

The latter instruction should produce a CRL of the following form:

```

>certmgr -crl -v Carl_20100401.crl
==============CRL # 1 ==========
Issuer::
  [0,0] 2.5.4.3 (CN) ValueType: 4
     43 61 72 6C 52 53 41                               'CarlRSA'
ThisUpdate::
  Thu Apr 01 20:00:00 2010
NextUpdate::
  Sat May 01 08:00:00 2010
SHA1 Thumbprint::
      BAE05E5B E4F5E7A7 82F487CC 60F7BC31 0A643538
MD5 Thumbprint::
      20E8251E 7959BE61 41441901 60DB7FBA
Version:: 0
SignatureAlgorithm:: 1.2.840.113549.1.1.5
SignatureAlgorithm.Parameters::
     05 00                                              '..'
-----  Entries  -----
 [0] SerialNumber:: 01
 [0] RevocationDate:: Mon Dec 31 08:00:00 2007
 [0] Extensions:: NONE
 [1] SerialNumber:: 02
 [1] RevocationDate:: Thu Dec 31 20:59:59 2009
 [1] Extensions:: NONE
 [2] SerialNumber:: 01 01 D0
 [2] RevocationDate:: Fri Jan 01 08:00:00 2066
 [2] Extensions:: NONE
 [3] SerialNumber:: 01 02 DE AD BE EF
 [3] RevocationDate:: Sun Feb 28 09:01:59 2010
 [3] Extensions:: NONE
==============================================
CertMgr Succeeded

```

Note that the times given by CERTMGR are local, not GMT, and the output above is from a computer in a timezone 8 hours ahead of GMT.
Different times will be shown in different timezones.

### See Also

[X509_CheckCertInCRL](#X509_CheckCertInCRL)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_QueryCert"></a>X509_QueryCert
-----------------------------------------

Queries an X.509 certificate file for selected information.

### VBA/VB6 Syntax

`Public Declare Function X509_QueryCert Lib "diCrPKI.dll" 
    (ByVal strDataOut As String, ByVal nOutChars As Long, 
    ByVal strFileIn As String, ByVal strQuery As String, ByVal nOptions As Long) As Long`

`nRet = X509_QueryCert(strDataOut, nOutChars, strFileIn, strQuery,
    nOptions) As Long`

### C/C++ Syntax

`long __stdcall X509_QueryCert(char *szOutput, long nOutChars, const char *szCertFile, const char *szQuery, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive the output.

*nOutChars*
:   [in] specifying the length of the output string.

*szCertFile*
:   [in] with name of X.509 certificate file
	(or [base64 representation](#base64forcert)).

*szQuery*
:   [in] specifying the query (see Remarks below).

*nOptions*
:   [in] option flags:   

`PKI_DEFAULT` (0) for default options  

`PKI_QUERY_GETTYPE` to return the type of data returned for a given query.  

`PKI_X509_LATIN1` to try and convert Unicode/UTF-8/T.61 attribute strings to Latin-1 (ISO-8859-1)  

`PKI_X509_UTF8` to output attribute strings encoded in UTF-8 *[New in v20.3]*  

`PKI_X509_LDAP` to output the distinguished name in [LDAP string representation](#ldapstring) 
(for queries "issuerName" and "subjectName" only)
  

`PKI_X509_DECIMAL` to output the serial number in decimal format instead of hex
(for query "serialNumber" only)

### Returns (VBA/C)

If successful, the return value is a positive integer giving either the result itself 
(if the result is a number)
or the number of characters in the output string (if the query is looking for a string).
If the item queried is not present, the return value is zero.
If there is an error (e.g. a missing or invalid certificate file), it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`x509QueryCert`](#VB_x509QueryCert) (szCertFile As String, szQuery As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[X509.QueryCert Method](#M_X509_QueryCert)  

### C++ (STL) Equivalent

static std::string [dipki::X509::QueryCert](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#ac7b07eccfbb6ed11d98abd9808119633 "External link") (const std::string &certFile, const std::string &query, OutputOpts outOpts=OutputOpts::Default_OutputOpt)

### Python Equivalent

static [X509.query_cert](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.query_cert "External link")(filename, query, opts=0)

### Remarks

Valid queries are (case-insenitive): 

| Query String | Returns | Data Type |
| --- | --- | --- |
| `version` | X.509 version number, e.g. 1 or 3. | Number |
| `serialNumber` | Serial number in hex-encoded format | String |
| `signatureAlgorithm` | Signature algorithm used, e.g. `"sha1WithRSAEncryption"`. | String |
| `sigAlgId` | ID of signature algorithm used, see `PKI_SIG_*` values | Number |
| `signatureValue` | Signature value in hex-encoded format | String |
| `notBefore` | Date on which the certificate validity period begins in format `yyyy-mm-ddThh:nn:ssZ` | String |
| `notAfter` | Date on which the certificate validity period ends in format `yyyy-mm-ddThh:nn:ssZ` | String |
| `issuerName` | Distinguished name (DN) of entity who has signed and issued the certificate | String |
| `subjectName` | Distinguished name (DN) of the subject | String |
| `subjectPublicKeyAlgorithm` | Algorithm used in subject's public key,  e.g. `"dsa"` or `"rsaEncryption"`. | String |
| `subjectKeyIdentifier` | The subject key identifier extension, if present, in hex-encoded format | String |
| `authorityKeyIdentifier` | The authority key identifier extension, if present, in hex-encoded format | String |
| `rfc822Name` | First internet mail address found contained in a subjectAltName extension, if present | String |
| `isCA` | Returns 1 if the subject type is a CA, otherwise returns 0. | Number |
| `keyUsageString` | `keyUsage` flags in text format, e.g. `"digitalSignature,nonRepudiation"` | String |
| `extKeyUsageString` | `extKeyUsage` purposes in text format, e.g. `"codeSigning,timeStamping"` | String |
| `cRLDistributionPointsURI` | First URI found in `cRLDistributionPoints`, if any | String |
| `authorityInfoAccessURI` | First URI found in `authorityInfoAccess`, if any | String |
| `subjectAltName` | Subject alternative name extension, if present. *[New in v10.0]* | String |
| `hashAlgorithm` | Hash algorithm used in signature, e.g. `"sha256"`. *[New in v12.0]* | String |
| `pssParams` | Parameters used for RSA-PSS (if applicable). *[New in v12.0]* | String |

Some of these queries duplicate or complement existing functions:

* `"notBefore"` 	= [`X509_CertIssuedOn()`](#X509_CertIssuedOn)
* `"notAfter"` 	= [`X509_CertExpiresOn()`](#X509_CertExpiresOn)
* `"serialNumber"` 	= [`X509_CertSerialNumber()`](#X509_CertSerialNumber)
* `"subjectName"` 	= [`X509_CertSubjectName()`](#X509_CertSubjectName)
* `"issuerName"` 	= [`X509_CertIssuerName()`](#X509_CertIssuerName)

The "raw" VBA/C function behaves differently depending on whether the output is a string or a number. 
If the result data type is a number then it returns the value directly.
If the result is a string, then it sets *szOutput* and returns the number of characters in the string.
The required number of characters can be found by passing zero for *nOutChars* or a null string for *szOutput*.
ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

Note that the VBA wrapper function and the C#/`VB.NET` methods *always* return a string, which is different from the behaviour of the raw VB6/C function.

To find out the type of data returned for a given query, use the `PKI_QUERY_GETTYPE` option. 
The function will return either `PKI_QUERY_NUMBER` (1) or `PKI_QUERY_STRING` (2), 
or a negative "invalid query" error.
For example

```

nRet = X509_QueryCert("", 0, "", "version", PKI_QUERY_GETTYPE);

```

will return `PKI_QUERY_NUMBER`.

If an attribute value is encoded in a multi-byte-character string format (such as UTF8String or BMPString), 
the value will be expressed as a hexadecimal-encoded string *[NB changed in v3.9]*
preceded by the hash symbol (`'#'` U+0023), e.g.

```

"C=TW;O=E8 A1 8C E6 94 BF E9 99 A2" (v3.8 and earlier)
"C=TW;O=#E8A18CE694BFE999A2" (v3.9 and later)

```

 
Use the `PKI_X509_LATIN1` option to return the string encoded in Latin-1, if possible, to help with display issues.

The output from the queries `"issuerName"` and `"subjectName"` using the `PKI_X509_LDAP` option 
are suitable as content for the `<X509IssuerName>` and `<X509SubjectName>` nodes,
respectively, in the `<X509Data>` node of an XML-DSIG document.

### Example (VBA core function)

This example queries information from a sample X.509 certificate file.

```

Dim nRet As Long
Dim strOutput As String
Dim strQuery As String
Dim strCertFile As String

strCertFile = "CarlRSASelf.cer"

' Make a large buffer to receive output
strOutput = String(512, " ")

strQuery = "version"
nRet = X509_QueryCert(strOutput, Len(strOutput), strCertFile, strQuery, 0)
Debug.Print strQuery & "=" & nRet

strQuery = "serialNumber"
nRet = X509_QueryCert(strOutput, Len(strOutput), strCertFile, strQuery, 0)
If nRet <= 0 Then Exit Sub  ' catch error
Debug.Print strQuery & "=" & Left(strOutput, nRet)

strQuery = "signatureAlgorithm"
nRet = X509_QueryCert(strOutput, Len(strOutput), strCertFile, strQuery, 0)
If nRet <= 0 Then Exit Sub  ' catch error
Debug.Print strQuery & "=" & Left(strOutput, nRet)

strQuery = "notAfter"
nRet = X509_QueryCert(strOutput, Len(strOutput), strCertFile, strQuery, 0)
If nRet <= 0 Then Exit Sub  ' catch error
Debug.Print strQuery & "=" & Left(strOutput, nRet)

```

For the S/MIME test file `CarlRSASelf.cer`, the output is as follows

```

version=3
serialNumber=46346bc7800056bc11d36e2e9ff25020
signatureAlgorithm=sha1WithRSAEncryption
notAfter=2039-12-31T23:59:59Z

```

To query the type of data returned for a given query.

```

Dim nRet As Long
Dim strQuery As String

' Find out the data type for a given query
strQuery = "version"
nRet = X509_QueryCert("", 0, "", strQuery, PKI_QUERY_GETTYPE)
Debug.Print "Type(" & strQuery & ")=" & nRet

strQuery = "serialNumber"
nRet = X509_QueryCert("", 0, "", strQuery, PKI_QUERY_GETTYPE)
Debug.Print "Type(" & strQuery & ")=" & nRet

strQuery = "NotAValidQuery"
nRet = X509_QueryCert("", 0, "", strQuery, PKI_QUERY_GETTYPE)
Debug.Print "Type(" & strQuery & ")=" & nRet

```

This should produce output

```

Type(version)=1
Type(serialNumber)=2
Type(NotAValidQuery)=-29

```

where 1 (`PKI_QUERY_NUMBER`) indicates a number, 2 (`PKI_QUERY_STRING`) indicates a string, and -29 (`BAD_QUERY_ERROR`) indicates an invalid query.

### Example (VBA wrapper function)

```

Debug.Print x509TextDumpToString("AliceRSASignByCarl.cer")
Debug.Print x509QueryCert("AliceRSASignByCarl.cer", "subjectName")
Debug.Print asn1TextDumpToString("AliceRSASignByCarl.cer")

```

### See Also

[X509_KeyUsageFlags](#X509_KeyUsageFlags)
[X509_CertSubjectName](#X509_CertSubjectName)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_ReadCertStringFromP7Chain"></a>X509_ReadCertStringFromP7Chain
-------------------------------------------------------------------------

Reads an X.509 certificate into a base64 string from PKCS-7 "certs-only" data.

### VBA/VB6 Syntax

`Public Declare Function X509_ReadCertStringFromP7Chain Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strP7cFile As String, ByVal nIndex As Long, ByVal nOptions As Long) As Long`

`nRet = X509_ReadCertStringFromP7Chain(strOutput, nOutChars, strP7cFile, nIndex, nOptions) As Long`

### C/C++ Syntax

`long __stdcall X509_ReadCertStringFromP7Chain(char *szOutput, long nOutChars, const char *szP7cFile, long nIndex, long nOptions);`

### Parameters

*szOutput*
:   [out] string buffer to receive the output.

*nOutChars*
:   [in] size of the output buffer in bytes.

*szP7cFile*
:   [in] filename of a PKCS-7 "certs-only" file, or a string containing its [PEM textual representation](#pemstring).

*nIndex*
:   [in] specifying which certificate (1,2,...) in the chain to extract, 
	or (deprecated) 0 to return the count of certificates in the set.

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

If successful and *nIndex* is greater than zero, 
the return value is a positive number indicating the number of characters in or required for the output string,
which may be zero if no certificate could be found at the given index.
However, if *nIndex* is zero, it returns the *count* of certificates found in the list.
If an error occurred, it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`x509ReadCertStringFromP7Chain`](#VB_x509ReadCertStringFromP7Chain) (szP7cFile As String, nIndex As Long, Optional nOptions As Long = 0) As String

### .NET Equivalent

[X509.ReadCertStringFromP7Chain Method](#M_X509_ReadCertStringFromP7Chain)  

### C++ (STL) Equivalent

static std::string [dipki::X509::ReadCertStringFromP7Chain](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a340373ecfdf7a3d6560ef7f3829ad913 "External link") (const std::string &inputFile, int index)

### Python Equivalent

static [X509.read_cert_string_from_p7chain](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.read_cert_string_from_p7chain "External link")(inputfile, index)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The output is a [base64 string representation](#base64forcert) of the extracted X.509 certificate.

If *nIndex* is specified as a number greater than zero, the *nIndex*'th 
certificate found in the list, if any, 
will be extracted to a base64-encoded string which can be used to represent the X.509 certificate directly in this Toolkit.
 

This function will also extract certificates from CMS signed data objects, too.

*[New in v12.2]* To find the number of certificates in the chain, use [X509_GetCertCountInP7Chain](#X509_GetCertCountInP7Chain).
The old (deprecated) way to find the count of certificates was to set *nIndex* to zero. 

### Example (VBA core function)

The following example shows how to extract all the certificates from a PKCS-7 CertList file represented as a [PEM string](#pemstring). 
All transactions are carried out in memory.

```

Dim strP7 As String
Dim nCerts As Long
Dim nChars As Long
Dim nIndex As Long
Dim strCert As String
Dim strDigest As String * PKI_SHA1_CHARS
Dim strQuery As String * 128

' Input is a P7 chain file in PEM format
' bob.p7b (contains 2 X.509 certs: BobRSA and CarlRSA)
strP7 = "-----BEGIN PKCS7-----" & _
    "MIIERQYJKoZIhvcNAQcCoIIENjCCBDICAQExADALBgkqhkiG9w0BBwGgggQaMIICJzCCAZCgAwIB" & _
    "AgIQRjRrx4AAVrwR024uzV1x0DANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwdDYXJsUlNBMB4X" & _
    "DTk5MDkxOTAxMDkwMloXDTM5MTIzMTIzNTk1OVowETEPMA0GA1UEAxMGQm9iUlNBMIGfMA0GCSqG" & _
    "SIb3DQEBAQUAA4GNADCBiQKBgQCp4WeYPznVX/Kgk0FepnmJhcg1XZqRW/sdAdoZcCYXD72lItA1" & _
    "hW16mGYUQVzPt7cIOwnJkbgZaTdt+WUee9mpMySjfzu7r0YBhjY0MssHA1lS/IWLMQS4zBgIFEjm" & _
    "Txz7XWDE4FwfU9N/U9hpAfEF+Hpw0b6Dxl84zxwsqmqn6wIDAQABo38wfTAMBgNVHRMBAf8EAjAA" & _
    "MA4GA1UdDwEB/wQEAwIFIDAfBgNVHSMEGDAWgBTp4JAnrHggeprTTPJCN04irp44uzAdBgNVHQ4E" & _
    "FgQU6PS4Z9izlqQq8xGqKdOVWoYWtCQwHQYDVR0RBBYwFIESQm9iUlNBQGV4YW1wbGUuY29tMA0G" & _
    "CSqGSIb3DQEBBQUAA4GBAHuOZsXxED8QIEyIcat7QGshM/pKld6dDltrlCEFwPLhfirNnJOIh/uL" & _
    "t359QWHh5NZt+eIEVWFFvGQnRMChvVl52R1kPCHWRbBdaDOS6qzxV+WBfZjmNZGjOd539OgcOync" & _
    "f1EHl/M28FAK3Zvetl44ESv7V+qJba3JiNiPzyvTMIIB6zCCAVSgAwIBAgIQRjRrx4AAVrwR024u" & _
    "n/JQIDANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwdDYXJsUlNBMB4XDTk5MDgxODA3MDAwMFoX" & _
    "DTM5MTIzMTIzNTk1OVowEjEQMA4GA1UEAxMHQ2FybFJTQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw" & _
    "gYkCgYEA5Ev/GLgkV/R3/25ze5NxXLwzGpKSciPYQUbQzRE6BLOOr4KdvVEeF3rydiwrhjmnvdeN" & _
    "GlPs5ADV6OyiNrHt4lDiMgmKP5+ZJY+4Tqu5fdWWZdoWoMW+Dq5EW+9e9Kcpy4LdrETpqpOUKQ74" & _
    "GNbIV17ydsTyEWA4uRs8HZfJavECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E" & _
    "BAMCAYYwHQYDVR0OBBYEFOngkCeseCB6mtNM8kI3TiKunji7MA0GCSqGSIb3DQEBBQUAA4GBALee" & _
    "1ATT7Snk/4mJFS5M2wzwSA8yYe7EBOwSXS3/D2RZfgrD7Rj941ZAN6cHtfA4EmFQ7e/dP+MLuGGl" & _
    "pJs85p6cVJq2ldbabDu1LUU1nUkBdvq5uTH5+WsSU6D1FGCbfco+8lNrsDdvreZ019v6WuoUQWNd" & _
    "zb7IDsHaao1TNBgCMQA=" & _
    "-----END PKCS7-----"
' Get count of certs in P7 chain - new function in [v12.2]
nIndex = 0
nCerts = X509_GetCertCountInP7Chain(strP7, 0)
Debug.Print "nCerts=" & nCerts
' Read all certs
For nIndex = 1 To nCerts
' Find required length of buffer
nChars = X509_ReadCertStringFromP7Chain(ByVal 0&, 0, strP7, nIndex, 0)
Debug.Print "X509_ReadCertStringFromP7Chain(" & nIndex & ") returns " & nChars
' Allocate memory/pre-dimension
strCert = String(nChars, " ")
nChars = X509_ReadCertStringFromP7Chain(strCert, Len(strCert), strP7, nIndex, 0)
' Cert is in a base64 string
Debug.Print Left(strCert, 150) & "..."
' Query the cert for subject name
nChars = X509_QueryCert(strQuery, Len(strQuery), strCert, "subjectName", 0)
Debug.Print "subjectName='" & Left(strQuery, nChars) & "'"
' Compute the SHA-1 thumbprint of the cert
nChars = X509_CertThumb(strCert, strDigest, Len(strDigest), 0)
Debug.Print "SHA-1(cert)=" & Left(strDigest, nChars)
Next

```

This should result in output as follows:

```

nCerts=2
X509_ReadCertStringFromP7Chain(1) returns 740
MIICJzCCAZCgAwIBAgIQRjRrx4AAVrwR024uzV1x0DANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwdDYXJsUlNBMB4XDTk5MDkxOTAxMDkwMloXDTM5MTIzMTIzNTk1OVowETEPMA0GA1UEAxMGQm...
subjectName='CN=BobRSA'
SHA-1(cert)=63f046d2dd7042e51fdc26a511ef7c81ea622d8b
X509_ReadCertStringFromP7Chain(2) returns 660
MIIB6zCCAVSgAwIBAgIQRjRrx4AAVrwR024un/JQIDANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwdDYXJsUlNBMB4XDTk5MDgxODA3MDAwMFoXDTM5MTIzMTIzNTk1OVowEjEQMA4GA1UEAxMHQ2...
subjectName='CN=CarlRSA'
SHA-1(cert)=4110908f77c64c0edfc2de6273bfa9a98a9c5ce5

```

### Example (VBA wrapper function)

```

Dim strCertString As String
strCertString = x509ReadStringFromFile("AliceRSASignByCarl.cer")
Debug.Print strCertString
Debug.Print "CertThumb=" & x509CertThumb(strCertString)
strCertString = x509ReadCertStringFromP7Chain("alice_bob_carl_certs.p7c", 3)
Debug.Print strCertString
Debug.Print "CertThumb=" & x509CertThumb(strCertString)
Debug.Print "HashIssuerAndSN=" & x509HashIssuerAndSN(strCertString, PKI_HASH_SHA256)

'Invalid index
strCertString = x509ReadCertStringFromP7Chain("alice_bob_carl_certs.p7c", 0)
Debug.Print "[" & strCertString & "]"

Dim strP7File As String
Dim nIndex As Long
Dim nCerts As Long
strP7File = "alice_bob_carl_certs.p7c"
' Call core fn with zero index to find count
nCerts = X509_ReadCertStringFromP7Chain("", 0, strP7File, 0, 0)
Debug.Print "nCerts=" & nCerts
For nIndex = 1 To nCerts
    strCertString = x509ReadCertStringFromP7Chain(strP7File, nIndex)
    Debug.Print "subjectName: " & x509QueryCert(strCertString, "subjectName")
Next

```

### See Also

[X509_GetCertFromP7Chain](#X509_GetCertFromP7Chain)
[X509_GetCertCountInP7Chain](#X509_GetCertCountInP7Chain)
[CMS_QuerySigData](#CMS_QuerySigData)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_ReadCertStringFromPFX"></a>X509_ReadCertStringFromPFX
-----------------------------------------------------------------

Reads an X.509 certificate into a base64 string from PKCS-12 PFX/.p12 data.

### VBA/VB6 Syntax

`Public Declare Function X509_ReadCertStringFromPFX Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strPfxFile As String, ByVal strPassword As String, ByVal nOptions As Long) As Long`

`nRet = X509_ReadCertStringFromPFX(strOutput, nOutChars, strPfxFile, strPassword, nOptions) As Long`

### C/C++ Syntax

`long __stdcall X509_ReadCertStringFromPFX(char *szOutput, long nOutChars, const char *szPfxFile, const char *szPassword, long nOptions);`

### Parameters

*szOutput*
:   [out] string buffer to receive the output.

*nOutChars*
:   [in] size of the output buffer in bytes.

*szPfxFile*
:   [in] filename of a PFX file, or a string containing its [PEM textual representation](#pemstring).

*szPassword*
:   [in] containing password or `""` if certificate is not encrypted

*nOptions*
:   [in] option flags:  not used in this release. Specify zero.

### Returns (VBA/C)

If successful, the return value is a positive number indicating the number of characters in or required for the output string; otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`x509ReadCertStringFromPFX`](#VB_x509ReadCertStringFromPFX) (szPfxFile As String, szPassword As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[X509.ReadCertStringFromPFX Method](#M_X509_ReadCertStringFromPFX)  

### C++ (STL) Equivalent

static std::string [dipki::X509::ReadCertStringFromPFX](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a737485c8b333f51e80f7eab8ca4dc978 "External link") (const std::string &inputFile, const std::string &password)

### Python Equivalent

static [X509.read_cert_string_from_pfx](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.read_cert_string_from_pfx "External link")(inputfile, password)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The default behaviour is to extract one certificate from the PFX file and output as a [base64 string representation](#base64forcert) of the extracted X.509 certificate.
It will attempt to find a matching certificate for any private key, otherwise it will save
the first `pkcs-12-certBag` found in the PFX file containing a `x509Certificate`. 

Both unencrypted certificates and certificates encrypted with the weak 40-bit encryption used by "default"
in Microsoft and OpenSSL PKCS-12 files are supported, but not any other encryption algorithm.

If no certificate can be found the function will return a negative `NO_DATA_ERROR` error code.

### Example (VBA core function)

```

Dim strPfx As String
Dim nChars As Long
Dim strCert As String
Dim strDigest As String * PKI_SHA1_CHARS
Dim strQuery As String * 128
Dim strPassword As String

' Input is a PFX file in PEM format
' bob.pfx (password="password")
strPfx = "-----BEGIN PKCS12-----" & _
    "MIIGhAIBAzCCBkoGCSqGSIb3DQEHAaCCBjsEggY3MIIGMzCCAv8GCSqGSIb3DQEHBqCCAvAwggLsAgEAMIIC5QYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQIawU" & _
    "AVTFvAiECAggAgIICuNwEuFcRnZamZyMyIn+vH+wC5BVUtZAWNrlIqToezF7cYqt/18+HXB/46nllz+qUD3Dv9rS78MnPeAM47afFRTricHsiOpE+2eXf32lxduoF5+" & _
    "CLS3S7TAhRUMp2Fh18LlukzK9lY67BGfU9Y3yCukTmwVXqe49dkj8y9JjVJhXnoc2c7eOk3o5RjXHFsAMHwirqdsESHstrDZYLMVGw5HnAamY7zQd8WUpIweAFaEDLJ" & _
    "fyzqY1/LTL/txvZ9VQ/B/36HKyEpoIvuH6iOCBkebpJwWSkkffuVFbUfMLguMztL/sf+jE2NiuljSBJ9pTNsZziZWERb6CxZH0a2xkkBTciXM5Dl5efWL0GmBg+aJSI" & _
    "yh+Gw5W8Q7gmnH6H9myszvW9uYv/epwCbIpHd0dRHPbL3fR4KGhFexq24tAG86tDqPKb6H6n0lSA+Oq46SwZ00xIFpVcFaO/8yVqf6+JRDGoZ55aAZF6OCi7R1GvI+6" & _
    "pzz37pvP7SWfqVSuXCTNQq9uKw97SH5YftQ9hkELQ4vHCjFh4UJSBUCZgDtqR1uB/+44H5UpP8KvbETaOFJszMxsqXBMqc1uEODSNg+EHEx+yg7Bx1CcNrm+6rtThC4" & _
    "9+ow18HDMxbn3lAw1ooblANvSzR4YTt68N/4dtwROOdXjwKzyg03qWK2sJaiH5LzbB5MMmrdAChb9dLoRKBN2LREob7KRKEs6v51IW1yq4UCwSmpP+RbchZwIoKVXx/" & _
    "MYKjVqzGfZAgBRpXEq/KH/8R+ttFPKdab2GAEjd7hIOmetp5einQmK4C7JYE6Uyabf1IImtVhBw2dGU3GiM2zSIGqCx3bmYETZheMTAV9MMVUYe8gQeEpbXM4GAnwX0" & _
    "wpS0aYapzGeA/62X2nFh21eRHVzUcf0miXVvyOy6a1vj6O6N5F1jVaCV3jCCAywGCSqGSIb3DQEHAaCCAx0EggMZMIIDFTCCAxEGCyqGSIb3DQEMCgECoIICpjCCAqI" & _
    "wHAYKKoZIhvcNAQwBAzAOBAjw/dx4SlLcWwICCAAEggKALm91I8gYuPpRTCSn5pN4OQBLbI6jSW+9FGeNYvOy/+Pt3Oq0i15ZXZZez7dP8rdb0tmTCSZwVPIwtJRKxY" & _
    "UNaTppUTWZhXhnmeTMtSZpFuKmo6UhW8lGUcg45sO5UKUtdH0/UgewaSUfV4L06vp4j7Fugwbp666seJJ/9vQwMAxoqj0blxNNmASAcW7yj/lA2/p4KuGlnGkv4MSW5" & _
    "ViH7T24VeFXTzyFFR7UR1Nw9Blr5jdr7b2rZSdTj0GeHZ/L3FksFWJocl8PEEL4ZdVscbvO+l7vtbeBz0y9TDr/HUwt2tfqXgjckVVoJhmsczJXrG5Ai+brKnGQ7R5u" & _
    "IpIsqd9O6EpG68VMMGA5iSKsLYtibieqom8mRO00sFiQharxONEdveY+3O98nG6xzHlaBdNbxVo38Y+4LK6Gc81dUWYwss3ajdiJWe0+TYQjMPF72eWctcQAoTxITpd" & _
    "/j6rD7EmvLVyPIR46L4w6Gb/uz5G1T1UiLoh9luM1nRKKICyo2XllZDNO0msaub7DH1xzJzEy2OT9cwChqYfKKeWEE2BWL699fmq5RMCbIQVtE2bJDP8obu9j6HLskC" & _
    "iZcJm6nC7IKS1pQ2BA/JJVKxC8ADuLOAOdicWquDd8MWL5a9HpXd5TtUlfiRecTw8IRozTLaoDVlhaYNGPzwkjL9zZ+Up5Uy6HHXMDb0aD0fgvMqdAspB1+Xlt2RgP6" & _
    "CnEH2hwQqGFoA8TtijeS+DtdMy8BxJ7g1fiEH0+4UISl1vymjPI1MJCI1VlFLvpjZvKHluwjgp1SHk3tFRJLJ8a/eApvmscKXSlxcYz+5Bv8dxPGdhO/KOLQS7XZ4a8" & _
    "VSg977WS1jFYMCMGCSqGSIb3DQEJFTEWBBRj8EbS3XBC5R/cJqUR73yB6mItizAxBgkqhkiG9w0BCRQxJB4iAEIAbwBiACcAcwAgAGYAcgBpAGUAbgBkAGwAeQAgAEk" & _
    "ARDAxMCEwCQYFKw4DAhoFAAQUaHSMUJ415FfKGv3cZpwloKDmqgYECAreM3EkHVjCAgIIAA==" & _
    "-----END PKCS12-----"

' Read in cert as string from PFX/P12 data
' Find required length of buffer
nChars = X509_ReadCertStringFromPFX(ByVal 0&, 0, strPfx, "password", 0)
Debug.Print "X509_ReadCertStringFromPFX() returns " & nChars
' Allocate memory/pre-dimension
strCert = String(nChars, " ")
nChars = X509_ReadCertStringFromPFX(strCert, Len(strCert), strPfx, "password", 0)
' Cert is in a base64 string
Debug.Print Left(strCert, 150) & "..."
' Query the cert for subject name
nChars = X509_QueryCert(strQuery, Len(strQuery), strCert, "subjectName", 0)
Debug.Print "subjectName='" & Left(strQuery, nChars) & "'"
' Compute the SHA-1 thumbprint of the cert
nChars = X509_CertThumb(strCert, strDigest, Len(strDigest), 0)
Debug.Print "SHA-1(cert)=" & Left(strDigest, nChars)

```

This should result in output as follows:

```

X509_ReadCertStringFromPFX() returns 740
MIICJzCCAZCgAwIBAgIQRjRrx4AAVrwR024uzV1x0DANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwdDYXJsUlNBMB4XDTk5MDkxOTAxMDkwMloXDTM5MTIzMTIzNTk1OVowETEPMA0GA1UEAxMGQm...
subjectName='CN=BobRSA'
SHA-1(cert)=63f046d2dd7042e51fdc26a511ef7c81ea622d8b

```

### Example (VBA wrapper function)

```

Dim strCertString As String
strCertString = x509ReadCertStringFromPFX("alice.p12", "password")
Debug.Print strCertString
Debug.Print "CertThumb=" & x509CertThumb(strCertString)
Debug.Print "HashIssuerAndSN=" & x509HashIssuerAndSN(strCertString)

```

### See Also

[X509_GetCertFromPFX](#X509_GetCertFromPFX)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_ReadStringFromFile"></a>X509_ReadStringFromFile
-----------------------------------------------------------

Creates a base64 string of an X.509 certificate file.

### VBA/VB6 Syntax

`Public Declare Function X509_ReadStringFromFile Lib "diCrPKI.dll" 
(ByVal strOutput As String, ByVal nOutChars As Long, ByVal strCertFile As String, ByVal nOptions As Long) As Long`

`nRet = X509_ReadStringFromFile(strOutput, nOutChars, strCertFile, nOptions) As Long`

### C/C++ Syntax

`long __stdcall X509_ReadStringFromFile(char *szOutput, long nOutChars, const char *szCertFile, long nOptions);`

### Parameters

*szOutput*
:   [out] to receive the output.

*nOutChars*
:   [in] specifying the length of the output string.

*szCertFile*
:   [in] with name of X.509 certificate file.

*nOptions*
:   [in] option flags: not used. Set to zero.

### Returns (VBA/C)

If successful, the return value is a positive number indicating the number of characters
in the output string; otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`x509ReadStringFromFile`](#VB_x509ReadStringFromFile) (szCertFile As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[X509.ReadStringFromFile Method](#M_X509_ReadStringFromFile)  

### C++ (STL) Equivalent

static std::string [dipki::X509::ReadStringFromFile](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a44e353950105afd924a2b2cdede7e956 "External link") (const std::string &certFile)

### Python Equivalent

static [X509.read_string_from_file](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.read_string_from_file "External link")(certfilename)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

This function reads in the complete X.509 certificate as a continuous base64 string. 
The same certificate will *always* produce exactly the same string.
This string can be used, for
example, when creating an XML file which requires the certificate as an attribute, e.g.

```

<?xml version="1.0" encoding="UTF-8"?>
<Comprobante fecha="2005-09-02T16:30:00" folio="1" noAprobacion="1" 
noCertificado="00001000000000000114" 
certificado="MIIDWjCCAkKgAwIBAgIUMDAwMDExMDAwMDAyMDA..."
serie="A" version="1.0">

```

The output string must be long enough to receive the *complete* output or a `SHORT_BUF_ERROR` error will result.

### Example (VBA core function)

This example reads in the base64 string from the SAT Mexico test certificate and displays it.
It then saves the string as a new certificate and uses the 
[`X509_CertThumb`](#X509_CertThumb)
function to check that the two files are identical.

```

Dim nRet As Long
Dim strCertString As String
Dim strCertFile As String
Dim strNewFile As String
Dim strThumb1 As String
Dim strThumb2 As String

strCertFile = "aaa010101aaa_CSD.cer"
' Read in certificate file's data to a string
nRet = X509_ReadStringFromFile("", 0, strCertFile, 0)
Debug.Print "X509_ReadStringFromFile returns " & nRet
If nRet <= 0 Then Exit Sub  ' ERROR
strCertString = String(nRet, " ")
nRet = X509_ReadStringFromFile(strCertString, Len(strCertString), strCertFile, 0)
Debug.Print "For certificate '" & strCertFile & "':"
Debug.Print strCertString

' Save the string to a new certificate file, this time in PEM format
strNewFile = "aaa010101aaa_CSD.pem.cer"
nRet = X509_SaveFileFromString(strNewFile, strCertString, PKI_X509_FORMAT_PEM)
Debug.Print "X509_SaveFileFromString returns " & nRet
If nRet = 0 Then
    Debug.Print "Created new certificate file '" & strNewFile & "'"
End If

' Check that the two certificate files are identical by computing their SHA-1 thumbprints
strThumb1 = String(PKI_SHA1_CHARS, " ")
strThumb2 = String(PKI_SHA1_CHARS, " ")
nRet = X509_CertThumb(strCertFile, strThumb1, Len(strThumb1), 0)
nRet = X509_CertThumb(strNewFile, strThumb2, Len(strThumb2), 0)
Debug.Print "SHA-1(old)=" & strThumb1
Debug.Print "SHA-1(new)=" & strThumb2
If strThumb1 = strThumb2 Then
    Debug.Print "Certificates are identical"
Else
    Debug.Print "ERROR: certificates do not match"
End If

```

The output should look like this (the 1152-character certificate string has been edited)

```

X509_ReadStringFromFile returns 1152
For certificate 'aaa010101aaa_CSD.cer':
MIIDWjCCAkKgAwIBAgIUMDAwMDEx...7D5F8SB7Li3zt9vbbMzBc5xGg==
X509_SaveFileFromString returns 0
Created new certificate file 'aaa010101aaa_CSD.pem.cer'
SHA-1(old)=5791650d63340129568c1eecc6566b2fdd8bbd4c
SHA-1(new)=5791650d63340129568c1eecc6566b2fdd8bbd4c
Certificates are identical

```

### Example (VBA wrapper function)

```

Dim strCertString As String
strCertString = x509ReadStringFromFile("AliceRSASignByCarl.cer")
Debug.Print strCertString
Debug.Print "CertThumb=" & x509CertThumb(strCertString)
strCertString = x509ReadCertStringFromP7Chain("alice_bob_carl_certs.p7c", 3)
Debug.Print strCertString
Debug.Print "CertThumb=" & x509CertThumb(strCertString)
Debug.Print "HashIssuerAndSN=" & x509HashIssuerAndSN(strCertString, PKI_HASH_SHA256)

```

### See Also

[X509_SaveFileFromString](#X509_SaveFileFromString)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_SaveFileFromString"></a>X509_SaveFileFromString
-----------------------------------------------------------

Creates an X.509 certificate file from its base64 string representation.

### VBA/VB6 Syntax

`Public Declare Function X509_SaveFileFromString Lib "diCrPKI.dll" 
(ByVal strNewCertFile As String, ByVal strCertString As String, ByVal nOptions As Long) As Long`

`nRet = X509_SaveFileFromString(strNewCertFile, strCertString, nOptions)`

### C/C++ Syntax

`long __stdcall X509_SaveFileFromString(const char *szNewCertFile, const char *szCertString, long nOptions);`

### Parameters

*szNewCertFile*
:   [in] with name of X.509 certificate file to be created.

*szCertString*
:   [in] containing the base64 representation of the certificate.

*nOptions*
:   [in] option flags:   

`PKI_X509_FORMAT_PEM` to save the certificate in PEM format (default = DER-encoded binary)

### Returns (VBA/C)

If successful, the return value is zero; 
otherwise it returns a negative [error code](#errorcodes).

### .NET Equivalent

[X509.SaveFileFromString Method](#M_X509_SaveFileFromString)  

### C++ (STL) Equivalent

static int [dipki::X509::SaveFileFromString](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#aafcc3aa7a6a076b7f8f4dcb207e62fe4 "External link") (const std::string &newCertFile, const std::string &certString, bool inPEMFormat=false)

### Python Equivalent

static [X509.save_file_from_string](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.save_file_from_string "External link")(newcertfile, certstring, in_pem_format=False)

### Remarks

This function creates a new X.509 certificate file from a base64 string. 
It is the reverse of [`X509_ReadStringFromFile()`](#X509_ReadStringFromFile).
Any existing file of the same name will be overwritten without warning. 
The default option (`nOptions = 0`) is to save the file in binary (BER, DER) format. 
A PEM format file will start with `-----BEGIN CERTIFICATE-----` and will contain the same
base64 characters as in the certificate string. 
Both formats should be equally readable with the usual certificate manager programs
and both should have the same message digest "thumbprint".

### Example

See the example in [`X509_ReadStringFromFile`](#X509_ReadStringFromFile).

### See Also

[X509_ReadStringFromFile](#X509_ReadStringFromFile)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_TextDump"></a>X509_TextDump
---------------------------------------

Dumps details of an X.509 certificate
 (or a X.509 certificate revocation list (CRL) or a PKCS-10 certificate signing request (CSR))
 to a text file. 

### VBA/VB6 Syntax

`Public Declare Function X509_TextDump Lib "diCrPKI.dll" (ByVal strFileOut As String, ByVal strCertFile As String, ByVal nOptions As Long) As Long`

`nRet = X509_TextDump(strFileOut, strCertFile, nOptions)`

### C/C++ Syntax

`long __stdcall X509_TextDump(const char *szFileOut, const char *szCertFile, long nOptions);`

### Parameters

*szFileOut*
:   [in] with the filename of text file to be created.

*szCertFile*
:   [in] with the filename of Certificate file (or [base64 representation](#base64forcert)).

*nOptions*
:   [in] option flags:  

`PKI_X509_LATIN1` to try and convert UTF-8 attribute strings to Latin-1 (for display purposes).  

`PKI_X509_UTF8` to output attribute strings encoded in UTF-8 *[New in v20.3]*  

`PKI_X509_LDAP` to output the distinguished name in [LDAP string representation](#ldapstring). 

`PKI_X509_DECIMAL` to output the serial number in decimal format instead of hexadecimal.

### Returns (VBA/C)

If successful, the return value is zero; otherwise it returns a nonzero [error code](#errorcodes).

### .NET Equivalent

[X509.TextDump Method](#M_X509_TextDump) 

### Python Equivalent

static [X509.text_dump](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.text_dump "External link")(outputfile, certfile, opts=0)

### Remarks

The input file may be in binary BER/DER format or base64 PEM file format, 
or may be passed in [base64 representation](#base64forcert) or as a [PEM string](#pemstring).
It produces a text file containing the basic details of an X.509 certificate, X.509 certificate revocation list (CRL)
or PKCS-10 certificate signing request (CSR).

*[New in v12.3]* The notation `[!]` denotes a critical extension, e.g. `Key Usage[!]:`.

### Example

```

Dim nRet As Long
Dim strInputFile As String
Dim strOutFile As String

strInputFile = "AliceRSASignByCarl.cer"
strOutFile = "dump-AliceRSASignByCarl.cer.txt"
Debug.Print "File=" & strInputFile
nRet = X509_TextDump(strOutFile, strInputFile, 0)
Debug.Print "X509_TextDump returns " & nRet

```

The above example produces a text file with the following contents:

```

X.509 CERTIFICATE
Version: 3
Serial Number:
  #x46346BC7800056BC11D36E2EC410B3B0
Issuer:
  CN=CarlRSA
Subject:
  CN=AliceRSA
Validity:
  NotBefore: 1999-09-19T01:08:47Z
  NotAfter:  2039-12-31T23:59:59Z
Subject Public Key Algorithm: rsaEncryption
  RSA key length: 1024 bits
  Modulus:
    E0 89 73 39 8D D8 F5 F5 E8 87 76 39 7F 4E B0 05 
    BB 53 83 DE 0F B7 AB DC 7D C7 75 29 0D 05 2E 6D 
    12 DF A6 86 26 D4 D2 6F AA 58 29 FC 97 EC FA 82 
    51 0F 30 80 BE B1 50 9E 46 44 F1 2C BB D8 32 CF 
    C6 68 6F 07 D9 B0 60 AC BE EE 34 09 6A 13 F5 F7 
    05 05 93 DF 5E BA 35 56 D9 61 FF 19 7F C9 81 E6 
    F8 6C EA 87 40 70 EF AC 6D 2C 74 9F 2D FA 55 3A 
    B9 99 77 02 A6 48 52 8C 4E F3 57 38 57 74 57 5F 
  Exponent:
    01 00 01 
X509v3 Extensions:
  Subject Type: End Entity
  Key Usage[!]:
    digitalSignature,nonRepudiation
  Authority Key Identifier:
    e9e09027ac78207a9ad34cf242374e22ae9e38bb
  Subject Key Identifier:
    77d2b4d1b74c8a8aa3ce459dceec3ca03ae3ff50
  Subject Alternative Name:
    RFC822 Name: AliceRSA@example.com
Signature Algorithm: sha1WithRSAEncryption
Signature Hash Algorithm: sha1
Signature Value:
  3E 70 47 A8 48 CC 13 58 8F CA 51 71 6B 4E 36 18 
  5D 04 7E 80 B1 8D 4D CC CA A3 8F CC 7D 56 C8 BC 
  CF 6E B3 1C 59 A9 20 AA 05 81 A8 4E 25 AD A7 70 
  14 75 2F F5 C7 9B D1 0E E9 63 D2 64 B7 C6 66 6E 
  73 21 54 DF F4 BA 25 5D 7D 49 D3 94 6B 22 36 74 
  73 B8 4A EC 2F 64 ED D3 3D D2 A7 42 C5 E8 37 8A 
  B4 DB 9F 67 E4 BD 9F F9 FE 74 EF EA F9 EE 63 6A 
  D8 3F 4B 25 09 B5 D8 1A 76 AE EB 9B DB 49 B0 22 
SHA-1 Thumbprint:
  b30c48855055c2e64ce3196492d4b83831a6b3cb
SHA-256 Thumbprint:
  10e79a9993c26a87f2109ec1e81e0ac3ada0ee1bac1fe57fd85450e2c7c2406b

```

### See Also

[X509_QueryCert](#X509_QueryCert)
[ASN1_TextDump](#ASN1_TextDump)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_TextDumpToString"></a>X509_TextDumpToString
-------------------------------------------------------

Dumps details of an X.509 certificate
or a X.509 certificate revocation list (CRL) or a PKCS-10 certificate signing request (CSR)
 to a string. 

### VBA/VB6 Syntax

`Public Declare Function X509_TextDumpToString Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByVal strCertFile As String, ByVal nOptions As Long) As Long`

`nRet = X509_TextDumpToString(strOutput, nOutChars, strCertFile, nOptions)`

### C/C++ Syntax

`long __stdcall X509_TextDumpToString(char *szOutput, long nOutChars, const char *szCertFile, long nOptions);`

### Parameters

*szOutput*
:   [out] String buffer to receive output.

*nOutChars*
:   [in] Maximum number of characters to be received.

*szCertFile*
:   [in] Name of input file (or its [base64](#base64forcert) or [PEM string](#pemstring) representation).

*nOptions*
:   [in] option flags:  

`PKI_X509_LATIN1` to try and convert UTF-8 attribute strings to Latin-1 (for display purposes).  

`PKI_X509_UTF8` to output attribute strings encoded in UTF-8 (C/C++ only) *[New in v20.3]*  

`PKI_X509_LDAP` to output the distinguished name in [LDAP string representation](#ldapstring). 

`PKI_X509_DECIMAL` to output the serial number in decimal format instead of hexadecimal.

### Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`x509TextDumpToString`](#VB_x509TextDumpToString) (szCertFile As String, Optional nOptions As Long = 0) As String

### .NET Equivalent

[X509.TextDumpToString Method](#M_X509_TextDumpToString)  

### C++ (STL) Equivalent

static std::string [dipki::X509::TextDumpToString](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a9b8039568d9cd27430a5809956f06ed4 "External link") (const std::string &certFile, OutputOpts outOpts=OutputOpts::Default_OutputOpt)

### Python Equivalent

static [X509.text_dump_tostring](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.text_dump_tostring "External link")(certfile, opts=0)

### Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer *szOutput* of the required length. Specify a zero *nOutChars* or an empty string for *szOutput* to find the required length. ANSI C users [must add one to this value](#cusersaddone) when allocating memory.

The input file may be a an X.509 certificate, X.509 certificate revocation list (CRL) or PKCS-10 certificate signing request (CSR)
and may be a file in binary BER/DER or base64 PEM file format, 
or may be passed in [base64 representation](#base64forcert) or as a [PEM string](#pemstring).

The output string must be long enough to receive the *complete* output or a `SHORT_BUF_ERROR` error will result.

### Example (VBA core function)

```

Dim strInputFile As String
Dim strBuffer As String
Dim nChars As Long

strInputFile = "AliceRSASignByCarl.cer"
Debug.Print "File=" & strInputFile
' Query for required length
nChars = X509_TextDumpToString("", 0, strInputFile, PKI_X509_DECIMAL)
Debug.Print "X509_TextDumpToString returns " & nChars
' Dimension output buffer
strBuffer = String(nChars, " ")
nChars = X509_TextDumpToString(strBuffer, Len(strBuffer), strInputFile, PKI_X509_DECIMAL)
Debug.Print strBuffer

```

```

File=AliceRSASignByCarl.cer
X509_TextDumpToString returns 1692
X.509 CERTIFICATE
Version: 3
Serial Number:
  93318145165434344057210696409401045936
Issuer:
  CN=CarlRSA
...[cut]...

```

### Example (VBA wrapper function)

```

Debug.Print x509TextDumpToString("AliceRSASignByCarl.cer")
Debug.Print x509QueryCert("AliceRSASignByCarl.cer", "subjectName")
Debug.Print asn1TextDumpToString("AliceRSASignByCarl.cer")
```

### See Also

[X509_QueryCert](#X509_QueryCert)
[ASN1_TextDump](#ASN1_TextDump)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_ValidatePath"></a>X509_ValidatePath
-----------------------------------------------

Validates a certificate path.

### VBA/VB6 Syntax

`Public Declare Function X509_ValidatePath Lib "diCrPKI.dll" (ByVal strCertListOrP7File As String, ByVal strTrustedCert As String, ByVal nOptions As Long) As Long`

`nRet = X509_ValidatePath(strCertListOrP7File, strTrustedCert, nOptions)`

### C/C++ Syntax

`long __stdcall X509_ValidatePath(const char *szCertListOrP7File, const char *szTrustedCert, long nOptions);`

### Parameters

*szCertListOrP7File*
:   [in] either a list of certificate names separated by a semicolon or
the name of a PKCS-7 "certs-only" file containing the certificates to be validated.

*szTrustedCert*
:   [in] name of the trusted certificate (or [base64 representation](#base64forcert)).

*nOptions*
:   [in] option flags:   

`PKI_X509_NO_TIMECHECK` to avoid checking if the certificates are valid now (default = check validity dates against system clock).

### Returns (VBA/C)

Zero (0) if the certification path is valid.
If the certificates are otherwise of correct format but the validation fails, the return value is `PKI_X509_INVALID` (+43 = `CERT_PATH_ERROR`);
otherwise a *negative* [error code](#errorcodes).

### .NET Equivalent

[X509.ValidatePath Method](#M_X509_ValidatePath) (String)  

### Python Equivalent

static [X509.cert_path_is_valid](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.cert_path_is_valid "External link")(certlist, trustedcert="", no_timecheck=False)

### Remarks

A basic validation is carried out confirming that the subject of certificate `x` is the issuer of certificate `x+1`,
that certficate `x` was signed by certificate `x-1`, and that each certificate is valid as at the time on the system clock.
Only distinguished names are used to identify subjects and issuers, not alternative names or IDs. 
Certificate policies are ignored and no checks are made for revocation
(use [`X509_CheckCertInCRL()`](#X509_CheckCertInCRL) individually).
The order of the certificates in the input list is not important, but a complete chain must exist.
Note that the certificates must either all exist inside one .p7c cert chain file, or exist individually as .cer files.
In the latter case, specify all the file names in a semi-colon-separated list.
You can also pass the individual certificate information in its base64 representation rather than filenames, as in
`szCertList="MIHgMIGaAgE...se348UN/Q=;MIHgMIGaAgEB...9j8eEtvHw=;...etc`.

The *szTrustedCert* parameter is required unless a self-signed trust anchor is included in the list.
If there is no self-signed certificate, 
then you must specify a trusted certificate which has signed the certificate at the top of your chain. 
If specified, this must exist separately as a .cer file.

All certificates must be valid at the time the check is made or an error will result, unless
the `PKI_X509_NO_TIMECHECK` option is used. 
More information on the reason for an invalid certification path may be available by using
[`PKI_LastError()`](#PKI_LastError).

*[Changed in v12.0]* If the certificates are otherwise of correct format but the validation fails, this function returns `CERT_PATH_ERROR` (+43). 
Previous versions would return +1.

### Example

```

Dim nRet As Long
Dim strP7cFile As String
Dim strTrustedCert As String
Dim strCertList As String

' A p7c "certs-only" file which includes a self-signed cert
strP7cFile = "testcerts1.p7c"
nRet = X509_ValidatePath(strP7cFile, "", 0)
Debug.Print "X509_ValidatePath returns " & nRet & " (expected 0)"

' Same again but specify the trusted root cert
' (which is the same as the self-signed cert in the p7c file)
strP7cFile = "testcerts1.p7c"
strTrustedCert = "testcert00.cer"
nRet = X509_ValidatePath(strP7cFile, strTrustedCert, 0)
Debug.Print "X509_ValidatePath returns " & nRet & " (expected 0)"

' Specify a cert list - testcert00.cer is the self-signed cert
strCertList = "testcert00.cer;testcert03.cer;testcert01.cer;testcert02.cer"
nRet = X509_ValidatePath(strCertList, "", 0)
Debug.Print "X509_ValidatePath returns " & nRet & " (expected 0)"

' Same again but specify the trusted root cert (this time it is not in the list)
strCertList = "testcert01.cer;testcert02.cer;testcert03.cer"
strTrustedCert = "testcert00.cer"
nRet = X509_ValidatePath(strCertList, strTrustedCert, 0)
Debug.Print "X509_ValidatePath returns " & nRet & " (expected 0)"

```

### See Also

[X509_VerifyCert](#X509_VerifyCert)
[X509_CertIsValidNow](#X509_CertIsValidNow)
[X509_CheckCertInCRL](#X509_CheckCertInCRL)

[[Contents](#topofpage)] [[Index](#index)]

<a id="X509_VerifyCert"></a>X509_VerifyCert
-------------------------------------------

Verifies that an X.509 certificate -
 or X.509 certificate revocation list (CRL) or PKCS-10 certificate signing request (CSR) -
 has been signed by its issuer. 

### VBA/VB6 Syntax

`Public Declare Function X509_VerifyCert Lib "diCrPKI.dll" 
    (ByVal strCertToVerify As String, ByVal strIssuerCert As String, 
    ByVal nOptions As Long) As Long`

`nRet = X509_VerifyCert(strCertToVerify, 
    strIssuerCert, nOptions)`

### C/C++ Syntax

`long __stdcall X509_VerifyCert(const char *szCertToVerify, const char *szIssuerCert, long nOptions);`

### Parameters

*szCertToVerify*
:   [in] Name of the file to be verified (or a [PEM string](#pemstring)).

*szIssuerCert*
:   [in] Name of the issuer's certificate file (or a [PEM string](#pemstring)). Leave empty `""` for a PKCS#10 CSR.

*nOptions*
:   [in] option flags: not used in this release. Specify zero.

### Returns (VBA/C)

Zero (0) if the certificate's signature is valid.
If the certificate is otherwise of correct format but the validation fails, the return value is
`PKI_X509_VERIFY_FAILURE` (+22 = `SIGNATURE_ERROR`);
otherwise it returns a *positive* [error code](#errorcodes).

### .NET Equivalent

[X509.VerifyCert Method](#M_X509_VerifyCert)  

### Python Equivalent

static [X509.cert_is_verified](https://cryptosys.net/pki/pydocpki/class-stubs/X509.html#cryptosyspki.X509.cert_is_verified "External link")(certfile, issuercert)

### Remarks

This function verifies only that the certificate was signed by the owner of the public key in the issuer's certificate. 
It does not check the validity dates of either
certificate (to do that use [`X509_CertIsValidNow()`](#X509_CertIsValidNow)). 
Nor does it check that the certficate has been revoked 
(to do that use [`X509_CheckCertInCRL()`](#X509_CheckCertInCRL)). 
Only certificates signed with supported signature algorithms can be checked:
see [Supported Algorithms](#SupportedAlgorithms). 
The certificate file may be in binary BER/DER format or base64 PEM file format, 
or may be passed in [base64 representation](#base64forcert) or as a [PEM string](#pemstring).

This function can also be used to verify that an X.509 Certificate Revocation List (CRL) has been signed by the owner of the issuer's certificate
or that the self-signed signature in a PKCS#10 Certificate Signing Request (CSR) is valid.
Just pass the name of the file (or its PEM string form) as *szCertToVerify*.

*[New in v12.0]* A PKCS#10 Certificate Signing Request (CSR) contains its own public key which it can use to verify its own signature directly.
To verify a CSR, pass its name in *szCertToVerify* and set *szIssuerCert*`=""`. See example below.

*[Changed in v12.0]* If the certificate is otherwise of correct format but the validation fails, this function returns `SIGNATURE_ERROR` (22). 
Previous versions would return -1.

### Example

This example verifies that the certificate `myuser.cer` has been signed by the owner of `myca.cer`.

```

' Returns 0 if OK, PKI_X509_VERIFY_FAILURE if fails to validate, or +ve other error
Dim nRet As Long
nRet = X509_VerifyCert("myuser.cer", "myca.cer", 0)
If nRet = 0 Then
    Debug.Print "Verification is OK"
ElseIf nRet = PKI_X509_VERIFY_FAILURE Then
    Debug.Print "Cert not issued by this Issuer"
Else
    Debug.Print "Error: " & nRet & pkiGetLastError()
End If

```

This example verifies the signature in a PKCS#10 Certificate Signing Request.

```

Dim nRet As Long
nRet = X509_VerifyCert("myreq.p10.txt", "", 0)
If nRet = 0 Then
    Debug.Print "Verification is OK"
ElseIf nRet = PKI_X509_VERIFY_FAILURE Then
    Debug.Print "Signature is invalid"
Else
    Debug.Print "Error: " & nRet & pkiGetLastError()
End If

```

### See Also

[X509_CertIsValidNow](#X509_CertIsValidNow)
[X509_ValidatePath](#X509_ValidatePath)
[X509_CheckCertInCRL](#X509_CheckCertInCRL)

[[Contents](#topofpage)] [[Index](#index)]

<a id="XOF_Bytes"></a>XOF_Bytes
-------------------------------

Generate bytes using an extendable output function (XOF).

### VBA/VB6 Syntax

`Public Declare Function XOF_Bytes Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByRef lpMessage As Byte, ByVal nMsgLen As Long, ByVal nOptions As Long) As Long`

`nRet = XOF_Bytes(abOutput(0), nOutBytes, abMessage(0), nMsgLen, nOptions)
' Note the "(0)" after the byte array parameters`

### C/C++ Syntax

`long __stdcall XOF_Bytes(unsigned char *lpOutput, long nOutBytes, const void *lpMessage, long nMsgLen, long nOptions);`

### Parameters

*lpOutput*
:   [out] byte buffer to receive the output.

*nOutBytes*
:   [in] size of output buffer in bytes.

*lpMessage*
:   [in] byte array containing the input data.

*nMsgLen*
:   [in] length of the input data in bytes.

*nOptions*
:   [in] Option flags. Select one of:  

`PKI_XOF_SHAKE128` to use SHAKE128  

`PKI_XOF_SHAKE256` to use SHAKE256  

`PKI_XOF_MGF1_SHA1` to use MGF1-SHA-1  

`PKI_XOF_MGF1_SHA256` to use MGF1-SHA-256  

`PKI_XOF_MGF1_SHA512` to use MGF1-SHA-512

### Returns (VBA/C)

If successful, the return value is the number of bytes in the output;
otherwise it returns a negative [error code](#errorcodes).

### VBA Wrapper Syntax

Public Function [`xofBytes`](#VB_xofBytes) (nBytes As Long, lpMessage() As Byte, nOptions As Long) As Byte()

### .NET Equivalent

[Xof.Bytes Method](#M_Xof_Bytes)  

### C++ (STL) Equivalent

static bvec_t [dipki::Xof::Bytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_xof.html#a55cd586acc417fe248d8568bed801766 "External link") (int numBytes, const bvec_t &message, XofAlg xofalg)

### Python Equivalent

static [Xof.bytes](https://cryptosys.net/pki/pydocpki/class-stubs/Xof.html#cryptosyspki.Xof.bytes "External link")(numbytes, msg, xofalg)

### Remarks

The output buffer *lpOutput* must exist. It will be filled with exactly *nOutBytes* bytes.
Note there is no zero option for *nOptions*: a valid option flag must be specified.

SHAKE128 and SHAKE256 are described in [[FIPS202](#FIPS202)].
MGF1, despite its name as a *Mask Generation Function* (MGF), is also an eXtendable Output Function (XOF) using the SHA1/SHA-2 hash functions,
and is described in [[PKCS1](#PKCS1)].

### Example (VBA core function)

```

Dim strMsgHex As String
Dim nOutBits As Long
Dim nOutBytes As Long
Dim abOut() As Byte
Dim abMsg() As Byte
Dim nMsgLen As Long
Dim strOK As String
Dim nRet As Long
 
' Ref: "SHA-3 XOF Test Vectors for Byte-Oriented Output"
' File `SHAKE256VariableOut.rsp` COUNT = 1244
' <https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/sha3/shakebytetestvectors.zip>

' Input in hex form
strMsgHex = "6ae23f058f0f2264a18cd609acc26dd4dbc00f5c3ee9e13ecaea2bb5a2f0bb6b"
nOutBits = 2000
strOK = "b9b92544fb25cfe4ec6fe437d8da2bbe00f7bdaface3de97b8775a44d753c3adca3f7c6f183cc8647e229070439aa9539ae1f8f13470c9d3527fffdeef6c94f9f0520ff0c1ba8b16e16014e1af43ac6d94cb7929188cce9d7b02f81a2746f52ba16988e5f6d93298d778dfe05ea0ef256ae3728643ce3e29c794a0370e9ca6a8bf3e7a41e86770676ac106f7ae79e67027ce7b7b38efe27d253a52b5cb54d6eb4367a87736ed48cb45ef27f42683da140ed3295dfc575d3ea38cfc2a3697cc92864305407369b4abac054e497378dd9fd0c4b352ea3185ce1178b3dc1599df69db29259d4735320c8e7d33e8226620c9a1d22761f1d35bdff79a"
' Convert to byte array form
abMsg = cnvBytesFromHexStr(strMsgHex)
nMsgLen = UBound(abMsg) + 1

nOutBytes = (nOutBits / 8)
ReDim abOut(nOutBytes - 1)
nRet = XOF_Bytes(abOut(0), nOutBytes, abMsg(0), nMsgLen, PKI_XOF_SHAKE256)
If nRet > 0 Then
    Debug.Print "OUT=" & cnvHexStrFromBytes(abOut)
    Debug.Print "OK =" & strOK
Else
   Debug.Print "Error code " & nRet
End If

```

This should result in output as follows:

```

OUT=B9B92544FB25CFE4EC6FE437D8DA2BBE00F7BDAFACE3DE97B8775A44D753C3ADCA3F7C6F183CC8647E229070439AA9539AE1F8F13470C9D3527FFFDEEF6C94F9F0520FF0C1BA8B16E16014E1AF43AC6D94CB7929188CCE9D7B02F81A2746F52BA16988E5F6D93298D778DFE05EA0EF256AE3728643CE3E29C794A0370E9CA6A8BF3E7A41E86770676AC106F7AE79E67027CE7B7B38EFE27D253A52B5CB54D6EB4367A87736ED48CB45EF27F42683DA140ED3295DFC575D3EA38CFC2A3697CC92864305407369B4ABAC054E497378DD9FD0C4B352EA3185CE1178B3DC1599DF69DB29259D4735320C8E7D33E8226620C9A1D22761F1D35BDFF79A
OK =b9b92544fb25cfe4ec6fe437d8da2bbe00f7bdaface3de97b8775a44d753c3adca3f7c6f183cc8647e229070439aa9539ae1f8f13470c9d3527fffdeef6c94f9f0520ff0c1ba8b16e16014e1af43ac6d94cb7929188cce9d7b02f81a2746f52ba16988e5f6d93298d778dfe05ea0ef256ae3728643ce3e29c794a0370e9ca6a8bf3e7a41e86770676ac106f7ae79e67027ce7b7b38efe27d253a52b5cb54d6eb4367a87736ed48cb45ef27f42683da140ed3295dfc575d3ea38cfc2a3697cc92864305407369b4abac054e497378dd9fd0c4b352ea3185ce1178b3dc1599df69db29259d4735320c8e7d33e8226620c9a1d22761f1d35bdff79a

```

### Example (VBA wrapper function)

```

Dim lpMessage() As Byte
Dim lpOut() As Byte
lpMessage = cnvFromHex("6ae23f058f0f2264a18cd609acc26dd4dbc00f5c3ee9e13ecaea2bb5a2f0bb6b")
' Output 2000 bits
lpOut = xofBytes(2000 \ 8, lpMessage, PKI_XOF_SHAKE256)
Debug.Print "OUT=" & cnvToHex(lpOut)
Debug.Print "OK =" & "b9b92544fb25cf...f1d35bdff79a"
' MGF1-SHA-256
lpMessage = cnvFromHex("3b5c056af3ebba70d4c805380420585562b32410a778f558ff951252407647e3")
Debug.Print cnvToHex(lpMessage)
lpOut = xofBytes(34, lpMessage, PKI_XOF_MGF1_SHA256)
Debug.Print "OUT=" & cnvToHex(lpOut)
Debug.Print "OK =" & "5b7eb772aecf04c74af07d9d9c1c1f8d3a90dcda00d5bab1dc28daecdc86eb87611e"

```

### See Also

[`PRF_Bytes`](#PRF_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

<a id="vbawrapperfunctions"></a>VBA Wrapper Functions
-----------------------------------------------------

The wrapper functions for VBA/VB6 programmers are now all in `basCrPKI.bas`.
See [Notes on VBA wrapper functions](#notesonvbawrapperfunctions).

### <a id="vbawrapperfunctionlist"></a>VBA Wrapper Function List

* [asn1TextDumpToString](#VB_asn1TextDumpToString) - Dump details of ASN.1 formatted data to a string.
* [asn1Type](#VB_asn1Type) - Describe the type of ASN.1 data.
* [cipherDecryptAEAD](#VB_cipherDecryptAEAD) - Decrypt data using Authenticated Encryption with Associated Data (AEAD).
* [cipherDecryptBytes](#VB_cipherDecryptBytes) - Decrypts data in a byte array using the specified block cipher algorithm, mode and padding.
* [cipherDecryptHex](#VB_cipherDecryptHex) - Decrypt hex-encoded data using the specified block cipher algorithm, mode and padding.
* [cipherEncryptAEAD](#VB_cipherEncryptAEAD) - Encrypt data using Authenticated Encryption with Associated Data (AEAD).
* [cipherEncryptBytes](#VB_cipherEncryptBytes) - Encrypt data in a byte array using the specified block cipher algorithm, mode and padding.
* [cipherEncryptHex](#VB_cipherEncryptHex) - Encrypt hex-encoded data using the specified block cipher algorithm, mode and padding.
* [cipherFileDecrypt](#VB_cipherFileDecrypt) - Decrypt a file.
* [cipherFileEncrypt](#VB_cipherFileEncrypt) - Encrypt a file.
* [cipherKeyUnwrap](#VB_cipherKeyUnwrap) - Unwraps (decrypts) key material with a key-encryption key.
* [cipherKeyWrap](#VB_cipherKeyWrap) - Wraps (encrypts) key material with a key-encryption key.
* [cmsGetSigDataDigest](#VB_cmsGetSigDataDigest) - Extract the message digest from a signed-data CMS object file and verify the signature.
* [cmsMakeEnvData](#VB_cmsMakeEnvData) - Create a CMS enveloped-data object for one or more recipients.
* [cmsMakeEnvDataFromBytes](#VB_cmsMakeEnvDataFromBytes) - Create a CMS enveloped-data object from data in a byte array.
* [cmsMakeEnvDataFromString](#VB_cmsMakeEnvDataFromString) - Create a CMS enveloped-data object from an ASCII string.
* [cmsMakeSigData](#VB_cmsMakeSigData) - Create a CMS signed-data object from an input data file.
* [cmsMakeSigDataFromBytes](#VB_cmsMakeSigDataFromBytes) - Create a CMS signed-data object from data in a byte array.
* [cmsMakeSigDataFromSigValue](#VB_cmsMakeSigDataFromSigValue) - Create a CMS signed-data object using a pre-computed signature value.
* [cmsMakeSigDataFromString](#VB_cmsMakeSigDataFromString) - Create a CMS signed-data object from data in a string.
* [cmsQueryEnvData](#VB_cmsQueryEnvData) - Query a CMS enveloped-data object file for selected information.
* [cmsQuerySigData](#VB_cmsQuerySigData) - Query a CMS signed-data object file for selected information.
* [cmsReadEnvDataToBytes](#VB_cmsReadEnvDataToBytes) - Read and decrypt a CMS enveloped-data object to a byte array.
* [cmsReadEnvDataToString](#VB_cmsReadEnvDataToString) - Read and decrypt a CMS enveloped-data object to a string.
* [cmsReadSigDataToBytes](#VB_cmsReadSigDataToBytes) - Read the content from a CMS signed-data object directly into a byte array.
* [cmsReadSigDataToString](#VB_cmsReadSigDataToString) - Read the content from a CMS signed-data object directly into a string.
* [cmsVerifySigData](#VB_cmsVerifySigData) - Verify the signature and content of a signed-data CMS object file.
* [cnvB64Filter](#VB_cnvB64Filter) - Strip any invalid base64 characters from a string.
* [cnvB64StrFromBytes](#VB_cnvB64StrFromBytes) - Encode an array of bytes as a base64-encoded string.
* [cnvB64StrFromHexStr](#VB_cnvB64StrFromHexStr) - Re-encode a hexadecimal-encoded binary value as base64.
* [cnvB64StrFromString](#VB_cnvB64StrFromString) - Encode an ANSI string as a base64-encoded string.
* [cnvBase58FromBytes](#VB_cnvBase58FromBytes) - Convert 8-bit binary data to equivalent base58-encoded string format.
* [cnvBase58ToBytes](#VB_cnvBase58ToBytes) - Convert a base58-encoded string to an equivalent array of 8-bit unsigned integers.
* [cnvByteEncoding](#VB_cnvByteEncoding) - Convert encoding of byte array between UTF-8 and Latin-1.
* [cnvBytesFromB64Str](#VB_cnvBytesFromB64Str) - Decode a base64-encoded string as an array of Bytes.
* [cnvBytesFromHexStr](#VB_cnvBytesFromHexStr) - Decode a hexadecimal-encoded string as an array of Bytes.
* [cnvBytesLen](#VB_cnvBytesLen) - Find length of byte array.
* [cnvBytesMid](#VB_cnvBytesMid) - Return a substring of bytes of specified length from within a given byte array
* [cnvCheckUTF8Bytes](#VB_cnvCheckUTF8Bytes) - Check if a byte array contains valid UTF-8 characters.
* [cnvFromBase64](#VB_cnvFromBase64) - Decodes a base64-encoded string as an array of bytes.
* [cnvFromHex](#VB_cnvFromHex) - Decodes a hexadecimal-encoded string as an array of bytes.
* [cnvHexFilter](#VB_cnvHexFilter) - Strip any invalid hex characters from a hex string.
* [cnvHexFromBytesMid](#VB_cnvHexFromBytesMid) - Encode a substring of an array of bytes as a hexadecimal-encoded string.
* [cnvHexStrFromB64Str](#VB_cnvHexStrFromB64Str) - Re-encode a base64-encoded binary value as hexadecimal.
* [cnvHexStrFromBytes](#VB_cnvHexStrFromBytes) - Encode an array of bytes as a hexadecimal-encoded string.
* [cnvHexStrFromString](#VB_cnvHexStrFromString) - Encode an ANSI string as a hexadecimal-encoded string.
* [cnvLatin1FromUTF8Bytes](#VB_cnvLatin1FromUTF8Bytes) - Convert UTF-8 encoded array of bytes into a Latin-1 string, if possible.
* [cnvNumFromBytes](#VB_cnvNumFromBytes) - Convert the leftmost four bytes of an array to a 32-bit integer.
* [cnvNumToBytes](#VB_cnvNumToBytes) - Convert a 32-bit integer to an array of 4 bytes.
* [cnvReverseBytes](#VB_cnvReverseBytes) - Reverse the order of a byte array.
* [cnvStringFromHexStr](#VB_cnvStringFromHexStr) - Decode a hexadecimal-encoded string as an ANSI string.
* [cnvToBase64](#VB_cnvToBase64) - Encodes an array of bytes as a base64-encoded string.
* [cnvToHex](#VB_cnvToHex) - Encodes an array of bytes as a hexadecimal-encoded string.
* [cnvUTF8BytesFromLatin1](#VB_cnvUTF8BytesFromLatin1) - Convert a string of 8-bit Latin-1 (ISO-8859-1) characters into a UTF-8 encoded array of bytes.
* [comprCompress](#VB_comprCompress) - Compress data using zlib compression.
* [comprUncompress](#VB_comprUncompress) - Uncompress data using zlib compression.
* [eccDHSharedSecret](#VB_eccDHSharedSecret) - Compute EC Diffie-Hellman (ECDH) shared secret.
* [eccKeyHashCode](#VB_eccKeyHashCode) - Compute the hash code of an "internal" ECC public or private key string.
* [eccMakeKeys](#VB_eccMakeKeys) - Generate an EC public/private key pair and save as two key files.
* [eccPublicKeyFromPrivate](#VB_eccPublicKeyFromPrivate) - Convert an internal EC private key string into an internal EC public key string.
* [eccQueryKey](#VB_eccQueryKey) - Query an EC key string for selected information.
* [eccReadKeyByCurve](#VB_eccReadKeyByCurve) - Read an EC key from its hexadecimal representation.
* [eccReadPrivateKey](#VB_eccReadPrivateKey) - Read an EC private key from a file into an internal key string.
* [eccReadPublicKey](#VB_eccReadPublicKey) - Read an EC private key from a file into an internal key string.
* [eccSaveEncKey](#VB_eccSaveEncKey) - Save an internal EC private key string to an encrypted key file.
* [eccSaveKey](#VB_eccSaveKey) - Save an internal EC key string to a key file.
* [errFormatErrorMessage](#VB_errFormatErrorMessage) - Return an error message string for the last error.
* [hashBytes](#VB_hashBytes) - Compute hash digest in byte format of byte input.
* [hashFile](#VB_hashFile) - Compute hash digest in byte format of a file.
* [hashHexFromBytes](#VB_hashHexFromBytes) - Compute hash digest in hex format of byte input.
* [hashHexFromFile](#VB_hashHexFromFile) - Compute hash digest in hex format of a file.
* [hashHexFromHex](#VB_hashHexFromHex) - Compute hash digest in hex-encoded format from hex-encoded input.
* [hashLength](#VB_hashLength) - Return length of message digest output in bytes.
* [hmacBytes](#VB_hmacBytes) - Compute hash-based message authentication code (HMAC) as a byte array from byte data.
* [hmacHexFromBytes](#VB_hmacHexFromBytes) - Compute hash-based message authentication code (HMAC) in hexadecimal format from byte data.
* [hmacHexFromHex](#VB_hmacHexFromHex) - Compute hash-based message authentication code (HMAC) in hexadecimal format from data in hexadecimal-encoded strings.
* [hpkeDerivePrivateKey](#VB_hpkeDerivePrivateKey) - Derive an EC private key in a deterministic manner from input keying material using the DeriveKeyPair algorithm in RFC9180.
* [hpkeLabeledExpand](#VB_hpkeLabeledExpand) - Compute the output of the LabeledExpand function as defined in RFC9180.
* [hpkeLabeledExtract](#VB_hpkeLabeledExtract) - Compute the output of the LabeledExtract function as defined in RFC9180.
* [kdfBytes](#VB_kdfBytes) - Generate a key-encryption key (KEK) from input keying material (IKM) using a key derivation function (KDF).
* [kdfForCms](#VB_kdfForCms) - Generate a key-encryption key (KEK) for ECDH key exchange in a CMS EnvelopedData object.
* [ocspMakeRequest](#VB_ocspMakeRequest) - Create an Online Certification Status Protocol (OCSP) request as a base64 string.
* [ocspReadResponse](#VB_ocspReadResponse) - Read a response to an Online Certification Status Protocol (OCSP) request and outputs the main results in text form.
* [padBytesBlock](#VB_padBytesBlock) - Creates an input block suitably padded for encryption by a block cipher in ECB or CBC mode.
* [padHexBlock](#VB_padHexBlock) - Creates a hex-encoded input block suitably padded for encryption by a block cipher in ECB or CBC mode.
* [padUnpadBytes](#VB_padUnpadBytes) - Removes the padding from an encryption block.
* [padUnpadHex](#VB_padUnpadHex) - Removes the padding from a hex-encoded encryption block.
* [pbeKdf2](#VB_pbeKdf2) - Derives a key of any length from a password using the PBKDF2 algorithm from PKCS#5 v2.1.
* [pbeKdf2Hex](#VB_pbeKdf2Hex) - Derives a hex-encoded key of any length from a password using the PBKDF2 algorithm from PKCS#5 v2.1.
* [pbeScrypt](#VB_pbeScrypt) - Derives a key of any length from a password using the SCRYPT algorithm from RFC7914.
* [pbeScryptHex](#VB_pbeScryptHex) - Derives a hex-encoded key of any length from a password using the SCRYPT algorithm from RFC7914.
* [pfxMakeFile](#VB_pfxMakeFile) - Create a PFX (PKCS-12) file from an X.509 certificate and (optional) encrypted private key file.
* [pkiCompileTime](#VB_pkiCompileTime) - Get date and time the CryptoSys PKI DLL module was last compiled.
* [pkiErrorCode](#VB_pkiErrorCode) - Returns the error code of the error that occurred when calling the last function.
* [pkiErrorLookup](#VB_pkiErrorLookup) - Get error message associated with a given error code.
* [pkiLastError](#VB_pkiLastError) - Get last error message set by previous function.
* [pkiLicenceType](#VB_pkiLicenceType) - Returns the ASCII value of the licence type.
* [pkiModuleInfo](#VB_pkiModuleInfo) - Get additional information about the core DLL module.
* [pkiModuleName](#VB_pkiModuleName) - Get path name of the current process's module.
* [pkiPlatform](#VB_pkiPlatform) - Get platform the core DLL was compiled for.
* [pkiVersion](#VB_pkiVersion) - Get version number of native core DLL.
* [prfBytes](#VB_prfBytes) - Generate output bytes using a pseudorandom function (PRF).
* [pwdPrompt](#VB_pwdPrompt) - Prompt for a password in a dialog box.
* [rngBytes](#VB_rngBytes) - Generate random bytes.
* [rngGuid](#VB_rngGuid) - Generate a random 36-character Global Unique IDentifier (GUID) string.
* [rngInitialize](#VB_rngInitialize) - Initialize the RNG generator using a seed file.
* [rngInitializeEx](#VB_rngInitializeEx) - Query and initialize the RNG generator using Intel(R) DRNG, if available.
* [rsaDecodeMsg](#VB_rsaDecodeMsg) - Decode an EME or EMSA encoded message block according to PKCS#1.
* [rsaDecrypt](#VB_rsaDecrypt) - Decrypt a message encrypted using an RSA encryption scheme.
* [rsaEncodeMsg](#VB_rsaEncodeMsg) - Encode an EME or EMSA encoded message block according to PKCS#1.
* [rsaEncrypt](#VB_rsaEncrypt) - Encrypt a short message using RSA encryption.
* [rsaFromXMLString](#VB_rsaFromXMLString) - Create an RSA key string in internal format from an XML string.
* [rsaKeyBits](#VB_rsaKeyBits) - Get number of significant bits in RSA key modulus.
* [rsaKeyBytes](#VB_rsaKeyBytes) - Get number of bytes (octets) in RSA key modulus.
* [rsaKeyValue](#VB_rsaKeyValue) - Extract a base64-encoded RSA key value from internal key string.
* [rsaMakeKeys](#VB_rsaMakeKeys) - Generate an RSA public/private key pair and save as two key files.
* [rsaPublicKeyFromPrivate](#VB_rsaPublicKeyFromPrivate) - Convert an internal RSA private key string into an internal public key string.
* [rsaRawPrivate](#VB_rsaRawPrivate) - Carry out RSA transformation on raw data using private key.
* [rsaRawPublic](#VB_rsaRawPublic) - Carry out RSA transformation on raw data using public key.
* [rsaReadAnyPrivateKey](#VB_rsaReadAnyPrivateKey) - Read private key from a file or string containing a key into an "internal" public key string.
* [rsaReadAnyPublicKey](#VB_rsaReadAnyPublicKey) - Read public key from a file or string containing a key into an "internal" public key string.
* [rsaReadPrivateKey](#VB_rsaReadPrivateKey) - Read private key from a file or string containing a key into an "internal" public key string.
* [rsaReadPublicKey](#VB_rsaReadPublicKey) - Read public key from a file or string containing a key into an "internal" public key string.
* [rsaSaveEncKey](#VB_rsaSaveEncKey) - Save an internal RSA key string to an encrypted key file.
* [rsaSaveKey](#VB_rsaSaveKey) - Save an internal RSA key string to a key file.
* [rsaToXMLString](#VB_rsaToXMLString) - Create an XML string representation of an RSA internal key string.
* [rsaToXMLStringEx](#VB_rsaToXMLStringEx) - Create an XML string representation of an RSA internal key string with option to add a namespace prefix.
* [sigSignData](#VB_sigSignData) - Compute a signature value over data in a byte array.
* [sigSignFile](#VB_sigSignFile) - Compute a signature value over data in a file.
* [sigVerifyData](#VB_sigVerifyData) - Verify a signature value over data in a byte array.
* [smimeQuery](#VB_smimeQuery) - Query an S/MIME entity for selected information.
* [wipeBytes](#VB_wipeBytes) - Wipe a byte array securely.
* [wipeString](#VB_wipeString) - Wipe a string securely and return an empty string.
* [x509CertThumb](#VB_x509CertThumb) - Calculate the thumbprint (message digest value) of an X.509 certificate.
* [x509HashIssuerAndSN](#VB_x509HashIssuerAndSN) - Calculate the message digest hash of the PKCS #7 issuerAndSerialNumber value of an X.509 certificate.
* [x509QueryCert](#VB_x509QueryCert) - Query an X.509 certificate file for selected information.
* [x509ReadCertStringFromP7Chain](#VB_x509ReadCertStringFromP7Chain) - Read an X.509 certificate into a base64-encoded string from PKCS-7 "certs-only" data.
* [x509ReadCertStringFromPFX](#VB_x509ReadCertStringFromPFX) - Read an X.509 certificate into a base64-encoded string from PKCS-12 PFX/.p12 data.
* [x509ReadStringFromFile](#VB_x509ReadStringFromFile) - Read an X.509 certificate into a base64-encoded string.
* [x509TextDumpToString](#VB_x509TextDumpToString) - Dump details of an X.509 certificate or a X.509 certificate revocation list (CRL) or a PKCS-10 certificate signing request (CSR) to a string.
* [xofBytes](#VB_xofBytes) - Generate bytes using an eXtendable-Output Function (XOF).

### <a id="VB_asn1TextDumpToString"></a>asn1TextDumpToString

Dump details of ASN.1 formatted data to a string.

#### Syntax

[VBA]

```

Public Function asn1TextDumpToString ( _
    szFileOrPEMString As String, _
    Optional nOptions As Long = 0, _
    Optional szDirName As String = "" _
) As String

```

#### Parameters

szFileOrPEMString

:   Filename of ASN.1 formatted data file to be analyzed (or its base64 representation or PEM string).

nOptions

:   Use 0 for default or add any of:

```

PKI_ASN1_NOCOMMENTS
PKI_ASN1_ADDLEVELS
```

szDirName

:   Directory in which to create a temporary file. Specify `""` for default = system `TEMP` directory.

#### Return Value

`String:` String containing the output.

#### Remarks

Note different order of parameters from core function.

---

### <a id="VB_asn1Type"></a>asn1Type

Describe the type of ASN.1 data.

#### Syntax

[VBA]

```

Public Function asn1Type ( _
    szFileOrPEMString As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szFileOrPEMString

:   Filename of ASN.1 formatted data file to be analyzed (or a string containing its base64 or PEM representation).

nOptions

:   For future use.

#### Return Value

`String:` String containing the name of the type of ASN.1 data or the empty string if not found.

#### Remarks

Possible return values:

```

"EC PRIVATE KEY"
"OCSP REQUEST"
"OCSP RESPONSE"
"PKCS1 RSA PRIVATE KEY"
"PKCS1 RSA PUBLIC KEY"
"PKCS10 CERTIFICATE REQUEST"
"PKCS12 PFX"
"PKCS7 CERTIFICATE CHAIN"
"PKCS7/CMS COMPRESSED DATA"
"PKCS7/CMS DATA"
"PKCS7/CMS ENVELOPED DATA"
"PKCS7/CMS SIGNED DATA"
"PKCS8 ENCRYPTED PRIVATE KEY"
"PKCS8 PRIVATE KEY INFO"
"PUBLIC KEY INFO"
"X509 CERTIFICATE"
"X509 CRL"
```

---

### <a id="VB_cipherDecryptAEAD"></a>cipherDecryptAEAD

Decrypt data using Authenticated Encryption with Associated Data (AEAD).
The authentication tag is expected to be appended to the input ciphertext.

#### Syntax

[VBA]

```

Public Function cipherDecryptAEAD ( _
    lpInput() As Byte, _
    lpKey() As Byte, _
    lpIV() As Byte, _
    lpAAD() As Byte, _
    nOptions As Long _
) As Byte()

```

#### Parameters

lpInput

:   Input data to be decrypted.

lpKey

:   Key of exact length for algorithm (16, 24 or 32 bytes).

lpIV

:   Initialization Vector (IV) (aka nonce) exactly 12 bytes long.

lpAAD

:   Additional authenticated data (optional) - set as null to ignore.

nOptions

:   Algorithm to be used. Select one from

```

PKI_AEAD_AES_128_GCM
PKI_AEAD_AES_192_GCM
PKI_AEAD_AES_256_GCM
PKI_AEAD_CHACHA20_POLY1305
```

Add `PKI_IV_PREFIX` to expect the IV to be prepended at the start of the input.

#### Return Value

`Byte():` Plaintext in a byte array, or empty array on error (an empty array may also trivially be the correct result).

#### Remarks

The input must include the 16-byte tag appended to the ciphertext.

---

### <a id="VB_cipherDecryptBytes"></a>cipherDecryptBytes

Decrypts data in a byte array using the specified block cipher algorithm, mode and padding.
The key and initialization vector are passed as byte arrays.

#### Syntax

[VBA]

```

Public Function cipherDecryptBytes ( _
    lpInput() As Byte, _
    lpKey() As Byte, _
    lpIV() As Byte, _
    szAlgModePad As String, _
    Optional nOptions As Long = 0 _
) As Byte()

```

#### Parameters

lpInput

:   Input data to be decrypted.

lpKey

:   Key of exact length for block cipher algorithm.

lpIV

:   Initialization Vector (IV) of required size (if not provided in input) or empty array for ECB mode.

szAlgModePad

:   String with block cipher algorithm, mode and padding,
e.g. `"aes128/cbc/pkcs5"`

```

Alg:  aes128|aes192|aes256|tdea|3des|desede3
Mode: ecb|cbc|ofb|cfb|ctr|gcm
Pad:  pkcs5|nopad|oneandzeroes|ansix923|w3c
```

nOptions

:   Add `PKI_IV_PREFIX` to expect the IV to be prepended at the start of the input
(ignored for ECB mode).

#### Return Value

`Byte():` Decrypted plaintext in byte array or empty array on error.

#### Remarks

Default padding is `Pkcs5` for ECB and CBC mode and `NoPad` for all other modes.
GCM mode is only available with AES. The IV **must** be exactly 12 bytes long for GCM.

---

### <a id="VB_cipherDecryptHex"></a>cipherDecryptHex

Decrypt hex-encoded data using the specified block cipher algorithm, mode and padding.
The input data, key and initialization vector are all represented as hexadecimal strings.

#### Syntax

[VBA]

```

Public Function cipherDecryptHex ( _
    szInputHex As String, _
    szKeyHex As String, _
    szIvHex As String, _
    szAlgModePad As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szInputHex

:   Hex-encoded input data.

szKeyHex

:   Hex-encoded key of exact key length.

szIvHex

:   Hex-encoded IV of exact block length, ignored for ECB mode or if `PKI_IV_PREFIX` is used (use `""`).

szAlgModePad

:   String with block cipher algorithm, mode and padding,
e.g. `"aes128/cbc/pkcs5"`

```

Alg:  aes128|aes192|aes256|tdea|3des|desede3
Mode: ecb|cbc|ofb|cfb|ctr|gcm
Pad:  pkcs5|nopad|oneandzeroes|ansix923|w3c
```

nOptions

:   Add `PKI_IV_PREFIX` to expect the IV to be prepended before the ciphertext in the input (not applicable for ECB mode).

#### Return Value

`String:` Decrypted plaintext in hex-encoded string or empty string on error.

#### Remarks

Input data may be any even number of hex characters, but not zero.
Default padding is `Pkcs5` for ECB and CBC mode and `NoPad` for all other modes.
GCM mode is only available with AES. The IV **must** be exactly 12 bytes long for GCM.

---

### <a id="VB_cipherEncryptAEAD"></a>cipherEncryptAEAD

Encrypt data using Authenticated Encryption with Associated Data (AEAD).

#### Syntax

[VBA]

```

Public Function cipherEncryptAEAD ( _
    lpInput() As Byte, _
    lpKey() As Byte, _
    lpIV() As Byte, _
    lpAAD() As Byte, _
    nOptions As Long _
) As Byte()

```

#### Parameters

lpInput

:   Byte array containing the input data.

lpKey

:   Key of exact length for algorithm (16, 24 or 32 bytes).

lpIV

:   Initialization Vector (IV) (aka nonce) exactly 12 bytes long.

lpAAD

:   Additional authenticated data (optional) - set as empty array to ignore.

nOptions

:   Algorithm to be used. Select one from

```

PKI_AEAD_AES_128_GCM
PKI_AEAD_AES_192_GCM
PKI_AEAD_AES_256_GCM
PKI_AEAD_CHACHA20_POLY1305
```

and optionally add `PKI_IV_PREFIX` to prepend the IV (nonce) before the ciphertext in the output.

#### Return Value

`Byte():` Ciphertext with tag appended in a byte array, or empty array on error.

#### Remarks

The output will either be exactly 16 bytes longer than the input, or exactly 28 bytes longer if API_IV_PREFIX is used.

---

### <a id="VB_cipherEncryptBytes"></a>cipherEncryptBytes

Encrypt data in a byte array using the specified block cipher algorithm, mode and padding.
The key and initialization vector are passed as byte arrays.

#### Syntax

[VBA]

```

Public Function cipherEncryptBytes ( _
    lpInput() As Byte, _
    lpKey() As Byte, _
    lpIV() As Byte, _
    szAlgModePad As String, _
    Optional nOptions As Long = 0 _
) As Byte()

```

#### Parameters

lpInput

:   Input data to be encrypted.

lpKey

:   Key of exact length for block cipher algorithm.

lpIV

:   Initialization Vector (IV) of exactly the block size, empty array for ECB mode, or 12 bytes for AES-GCM.

szAlgModePad

:   String with block cipher algorithm, mode and padding,
e.g. `"aes128/cbc/pkcs5"`

```

Alg:  aes128|aes192|aes256|tdea|3des|desede3
Mode: ecb|cbc|ofb|cfb|ctr|gcm
Pad:  pkcs5|nopad|oneandzeroes|ansix923|w3c
```

nOptions

:   Add `PKI_IV_PREFIX` to prepend the IV before the ciphertext in the output
(ignored for ECB mode).

#### Return Value

`Byte():` Ciphertext in byte array or empty array on error.

#### Remarks

Default padding is `Pkcs5` for ECB and CBC mode and `NoPad` for all other modes.
GCM mode is only available with AES. The IV **must** be exactly 12 bytes long for GCM.

---

### <a id="VB_cipherEncryptHex"></a>cipherEncryptHex

Encrypt hex-encoded data using the specified block cipher algorithm, mode and padding.
The key and initialization vector are passed as hex-encoded strings.

#### Syntax

[VBA]

```

Public Function cipherEncryptHex ( _
    szInputHex As String, _
    szKeyHex As String, _
    szIvHex As String, _
    szAlgModePad As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szInputHex

:   Input data to be encrypted.

szKeyHex

:   Hex-encoded key of exact key length.

szIvHex

:   Hex-encoded IV of exact required length or `""` for ECB mode.

szAlgModePad

:   String with block cipher algorithm, mode and padding,
e.g. `"aes128/cbc/pkcs5"`

```

Alg:  aes128|aes192|aes256|tdea|3des|desede3
Mode: ecb|cbc|ofb|cfb|ctr|gcm
Pad:  pkcs5|nopad|oneandzeroes|ansix923|w3c
```

nOptions

:   Add `PKI_IV_PREFIX` to prepend the IV before the ciphertext in the output
(ignored for ECB mode).

#### Return Value

`String:` Encrypted ciphertext in hex-encoded string or empty string on error.

#### Remarks

Input data may be any even number of hex characters, but not zero.
Default padding is `Pkcs5` for ECB and CBC mode and `NoPad` for all other modes.
GCM mode is only available with AES. The IV **must** be exactly 12 bytes long for GCM.

---

### <a id="VB_cipherFileDecrypt"></a>cipherFileDecrypt

Decrypt a file.

#### Syntax

[VBA]

```

Public Function cipherFileDecrypt ( _
    szFileOut As String, _
    szFileIn As String, _
    lpKey() As Byte, _
    lpIV() As Byte, _
    szAlgModePad As String, _
    Optional nOptions As Long = 0 _
) As Long

```

#### Parameters

szFileOut

:   Name of output file to be created or overwritten.

szFileIn

:   Name of input file.

lpKey

:   Key of exact length for block cipher algorithm.

lpIV

:   Initialization Vector (IV) of required length, or empty array for ECB mode or if IV is prefixed.

szAlgModePad

:   String with block cipher algorithm, mode and padding,
e.g. `"aes128/cbc/pkcs5"`

```

Alg:  aes128|aes192|aes256|tdea|3des|desede3
Mode: ecb|cbc|ofb|cfb|ctr|gcm
Pad:  pkcs5|nopad|oneandzeroes|ansix923|w3c
```

nOptions

:   Add `PKI_IV_PREFIX` to expect the IV before the ciphertext in the input.

#### Return Value

`Long:` Zero on success or nonzero error code.

#### Remarks

`fileOut` and `fileIn` must **not** be the same.
GCM mode is only available with AES. The IV **must** be exactly 12 bytes long for GCM.

---

### <a id="VB_cipherFileEncrypt"></a>cipherFileEncrypt

Encrypt a file.

#### Syntax

[VBA]

```

Public Function cipherFileEncrypt ( _
    szFileOut As String, _
    szFileIn As String, _
    lpKey() As Byte, _
    lpIV() As Byte, _
    szAlgModePad As String, _
    Optional nOptions As Long = 0 _
) As Long

```

#### Parameters

szFileOut

:   Name of output file to be created or overwritten.

szFileIn

:   Name of input file.

lpKey

:   Key of exact length for block cipher algorithm.

lpIV

:   Initialization Vector (IV) of exactly the block size, empty array for ECB mode, or 12 bytes for AES-GCM.

szAlgModePad

:   String with block cipher algorithm, mode and padding,
e.g. `"aes128/cbc/pkcs5"`

```

Alg:  aes128|aes192|aes256|tdea|3des|desede3
Mode: ecb|cbc|ofb|cfb|ctr|gcm
Pad:  pkcs5|nopad|oneandzeroes|ansix923|w3c
```

nOptions

:   Add `PKI_IV_PREFIX` to prepend the IV before the ciphertext in the output
(ignored for ECB mode).

#### Return Value

`Long:` Zero on success or nonzero error code.

#### Remarks

`fileOut` and `fileIn` must **not** be the same.
GCM mode is only available with AES. The IV **must** be exactly 12 bytes long for GCM.

---

### <a id="VB_cipherKeyUnwrap"></a>cipherKeyUnwrap

Unwraps (decrypts) key material with a key-encryption key.

#### Syntax

[VBA]

```

Public Function cipherKeyUnwrap ( _
    lpData() As Byte, _
    lpKEK() As Byte, _
    nOptions As Long _
) As Byte()

```

#### Parameters

lpData

:   Wrapped key.

lpKEK

:   Key encryption key.

nOptions

:   Algorithm to be used. Select one from:

```

PKI_BC_AES128
PKI_BC_AES192
PKI_BC_AES256
PKI_BC_3DES
```

#### Return Value

`Byte():` Unwrapped key material (or empty array on error).

---

### <a id="VB_cipherKeyWrap"></a>cipherKeyWrap

Wraps (encrypts) key material with a key-encryption key.

#### Syntax

[VBA]

```

Public Function cipherKeyWrap ( _
    lpData() As Byte, _
    lpKEK() As Byte, _
    nOptions As Long _
) As Byte()

```

#### Parameters

lpData

:   Key material to be wrapped.

lpKEK

:   Key encryption key.

nOptions

:   Algorithm to be used. Select one from:

```

PKI_BC_AES128
PKI_BC_AES192
PKI_BC_AES256
PKI_BC_3DES
```

#### Return Value

`Byte():` Wrapped key (or empty array on error).

---

### <a id="VB_cmsGetSigDataDigest"></a>cmsGetSigDataDigest

Extract the message digest from a signed-data CMS object file and verify the signature.

#### Syntax

[VBA]

```

Public Function cmsGetSigDataDigest ( _
    szFileIn As String, _
    Optional szCertFile As String = "", _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szFileIn

:   Name of signed-data CMS object file or the data as a base64 or PEM string.

szCertFile

:   An (optional) X.509 certificate file to be used to identify the signer.

nOptions

:   For future use.

#### Return Value

`String:` Hash value in hex format or an empty string on error.

#### Remarks

If no certificate is given, it will use the first valid SignerInfo and certificate pair it finds in the SignedData.
RSASSA-PKCS1V1_5 only.

---

### <a id="VB_cmsMakeEnvData"></a>cmsMakeEnvData

Create a CMS enveloped-data object for one or more recipients.

#### Syntax

[VBA]

```

Public Function cmsMakeEnvData ( _
    szFileOut As String, _
    szFileIn As String, _
    szCertList As String, _
    Optional szKeyString As String = "", _
    Optional nOptions As Long = 0, _
    Optional nCount As Long = 0 _
) As Long

```

#### Parameters

szFileOut

:   Name of output file to be created.

szFileIn

:   Name of file containing input data.

szCertList

:   List of one or more recipient X.509 certificate filenames, separated by semicolons (;).
A certificate's representation in base64 or as a PEM string may be used instead of a filename.
Alternatively, specify a single PKCS#7 certificate chain file (.p7c/.p7b).
  
*Special cases:* Set as `"type=@pwri"` to create a single recipientInfo of the `PasswordRecipientInfo` (pwri) type;
or set as `"type=@kekri,keyid=<string>"` to create a single recipientInfo of the `KEKRecipientInfo` (kekri) type. See Remarks.

szKeyString

:   (formerly szSeed) Use to pass optional additional user key material (ukm) for KDF where KeyAgreement (kari) type or RSA-KEM is used.
Or use to pass the password for a pwri type or the key encryption key (KEK) for a kekri type.
Either pass a plain ASCII string, e.g. "abc" or use the format `"#x<hex-digits>"` to pass a string of arbitrary octet values,
e.g. `"#xdeadbeef01"` to pass the 5 bytes `0xde,0xad,0xbe,0xef,0x01`. Required for pwri and kekri types.

nOptions

:   Select the content encryption algorithm from:

```

PKI_BC_AES128 (default)
PKI_BC_AES192
PKI_BC_AES256
PKI_BC_3DES (legacy)
PKI_AEAD_AES_128_GCM
PKI_AEAD_AES_192_GCM
PKI_AEAD_AES_256_GCM
PKI_AEAD_CHACHA20_POLY1305
```

To set the key transport scheme (where applicable), use one of

```

PKI_KT_RSAES_PKCS (default)
PKI_KT_RSAES_OAEP
PKI_KEM_RSA
```

If you have selected `PKI_KT_RSAES_OAEP` then, optionally, add

```

PKI_MGF_MGF1SHA1
```

Select one hash algorithm where applicable:

```

PKI_HASH_SHA1 (default - CAUTION)
PKI_HASH_SHA224
PKI_HASH_SHA256
PKI_HASH_SHA384
PKI_HASH_SHA512
```

To set the key derivation function (KDF) (where applicable), add one of:

```

PKI_KDF_X963 (default for ECDH)
PKI_KDF_HKDF
PKI_KDF_KDF2
PKI_KDF_KDF3 (default for RSA-KEM)
```

add one key wrap algorithm for the ECDH key agreement scheme or the kekri key encryption algorithm or RSA-KEM (default=match content encryption algorithm):

```

PKI_KWRAP_3DES (legacy - allowed only if Triple DES is used for content encryption)
PKI_KWRAP_AES128
PKI_KWRAP_AES192
PKI_KWRAP_AES256
```

Optionally, add any of the bitflags:

```

PKI_CMS_FORMAT_BASE64 (default=binary)
PKI_CMS_ALT_ALGID
PKI_CMS_BIGFILE (binary file to binary file only)
PKI_CMS_USE_SKI to use subjectKeyIdentifier (SKI) instead of issuerAndSerialNumber for RecipientInfo
```

nCount

:   Use to pass the iteration count for a pwri type (default=4096) or tag length for AuthEnvelopedData (in range 12-16, default=16). Otherwise ignored.

#### Return Value

`Long:` Number of successful recipients or a negative error code.

#### Remarks

The `recipientInfo` type for each recipient is set automatically depending on the public key found in their certificate.
If RSA, the key transport technique (ktri) will be used; or RSA-KEM if option flag set.
If ECC, then the standard ECDH ephemeral-static key agreement technique (kari) will be used.

#### Example

```

' Create an enveloped CMS object (ktri type) to Bob using Bob's RSA key...
n = cmsMakeEnvData("cms2bob_aes128.p7m", "excontent.txt", "BobRSASignByCarl.cer", "", PKI_BC_AES128 Or PKI_KT_RSAES_OAEP)
' Same but using authenticated encryption and creating an authEnvelopedData object...
n = cmsMakeEnvData("cms2bob_aes128auth.p7m", "excontent.txt", "BobRSASignByCarl.cer", "", PKI_AEAD_AES_128_GCM Or PKI_KT_RSAES_OAEP)
' Create an enveloped CMS object (kari type) to Dana using Dana's ECC key...
n = cmsMakeEnvData("cms2dana_hkdf.p7m", "excontent.txt", "lamps-dana.encrypt.crt", "", PKI_BC_AES256 Or PKI_HASH_SHA256 Or PKI_KDF_HKDF Or PKI_KWRAP_AES256)
' Create an enveloped CMS object (kekri type) using a previously distributed symmetric key-encryption key (KEK)...
n = cmsMakeEnvData("cms_envdata_kekri.p7m", "excontent.txt", "type=@kekri,keyid=ourcommonkey", "#x0123456789ABCDEFF0E1D2C3B4A59687", PKI_BC_AES256 Or PKI_HASH_SHA256 Or PKI_KWRAP_AES128)
' Create an enveloped CMS object (pwri type) using password-based key management...
n = cmsMakeEnvData("cms_envdata_pwri.p7m", "excontent.txt", "type=@pwri", "password12345", PKI_BC_AES192)
```

---

### <a id="VB_cmsMakeEnvDataFromBytes"></a>cmsMakeEnvDataFromBytes

Create a CMS enveloped-data object from data in a byte array.

#### Syntax

[VBA]

```

Public Function cmsMakeEnvDataFromBytes ( _
    szFileOut As String, _
    lpInput() As Byte, _
    szCertList As String, _
    Optional szKeyString As String = "", _
    Optional nOptions As Long = 0, _
    Optional nCount As Long = 0 _
) As Long

```

#### Parameters

szFileOut

:   Name of output file to be created.

lpInput

:   Input data.

szCertList

:   List of one or more recipient X.509 certificate filenames, separated by semicolons (;).
A certificate's representation in base64 or as a PEM string may be used instead of a filename.
Alternatively, specify a single PKCS#7 certificate chain file (.p7c/.p7b).
  
*Special cases:* Set as `"type=@pwri"` to create a single recipientInfo of the `PasswordRecipientInfo` (pwri) type;
or set as `"type=@kekri,keyid=<string>"` to create a single recipientInfo of the `KEKRecipientInfo` (kekri) type. See Remarks.

szKeyString

:   (formerly szSeed) Use to pass optional additional user key material (ukm) for KDF where KeyAgreement (kari) type is used.
Or use to pass the password for a pwri type or the key encryption key (KEK) for a kekri type.
Either pass a plain ASCII string, e.g. "abc" or use the format `"#x<hex-digits>"` to pass a string of arbitrary octet values,
e.g. `"#xdeadbeef01"` to pass the 5 bytes `0xde,0xad,0xbe,0xef,0x01`. Required for pwri and kekri types.

nOptions

:   See the options in [cmsMakeEnvData](#VB_cmsMakeEnvData).

nCount

:   Use to pass the iteration count for a pwri type (default=4096) or tag length for AuthEnvelopedData (in range 12-16, default=16). Otherwise ignored.

#### Return Value

`Long:` Number of successful recipients or a negative error code.

#### Remarks

See remarks in [cmsMakeEnvData](#VB_cmsMakeEnvData)

---

### <a id="VB_cmsMakeEnvDataFromString"></a>cmsMakeEnvDataFromString

Create a CMS enveloped-data object from an ASCII string.

#### Syntax

[VBA]

```

Public Function cmsMakeEnvDataFromString ( _
    szFileOut As String, _
    szInput As String, _
    szCertList As String, _
    Optional szKeyString As String = "", _
    Optional nOptions As Long = 0, _
    Optional nCount As Long = 0 _
) As Long

```

#### Parameters

szFileOut

:   Name of output file to be created.

szInput

:   Input data.

szCertList

:   List of one or more recipient X.509 certificate filenames, separated by semicolons (;).
A certificate's representation in base64 or as a PEM string may be used instead of a filename.
Alternatively, specify a single PKCS#7 certificate chain file (.p7c/.p7b).
  
*Special cases:* Set as `"type=@pwri"` to create a single recipientInfo of the `PasswordRecipientInfo` (pwri) type;
or set as `"type=@kekri,keyid=<string>"` to create a single recipientInfo of the `KEKRecipientInfo` (kekri) type. See Remarks.

szKeyString

:   (formerly szSeed) Use to pass optional additional user key material (ukm) for KDF where KeyAgreement (kari) type is used.
Or use to pass the password for a pwri type or the key encryption key (KEK) for a kekri type.
Either pass a plain ASCII string, e.g. "abc" or use the format `"#x<hex-digits>"` to pass a string of arbitrary octet values,
e.g. `"#xdeadbeef01"` to pass the 5 bytes `0xde,0xad,0xbe,0xef,0x01`. Required for pwri and kekri types.

nOptions

:   See the options in [cmsMakeEnvData](#VB_cmsMakeEnvData).

nCount

:   Use to pass the iteration count for a pwri type (default=4096) or tag length for AuthEnvelopedData (in range 12-16, default=16). Otherwise ignored.

#### Return Value

`Long:` Number of successful recipients or a negative error code.

#### Remarks

See remarks in [cmsMakeEnvData](#VB_cmsMakeEnvData)

---

### <a id="VB_cmsMakeSigData"></a>cmsMakeSigData

Create a CMS signed-data object from an input data file.

#### Syntax

[VBA]

```

Public Function cmsMakeSigData ( _
    szFileOut As String, _
    szFileIn As String, _
    szCertList As String, _
    szPrivateKey As String, _
    Optional nOptions As Long = 0 _
) As Long

```

#### Parameters

szFileOut

:   Name of output file to be created.

szFileIn

:   Name of file containing message data to be signed.

szCertList

:   Filename of the signer's certificate (or a string with its base64 or PEM representation)
and (optionally) a list of other certificates to be included in the output, separated by semi-colons (;)
Alternatively, specify a single PKCS#7 certificate chain file (.p7c/.p7b) containing the signer's certificate.

szPrivateKey

:   Internal representation of private key for the sender.

nOptions

:   Select the signature algorithm from one of:

```

PKI_SIG_RSA_SHA1
PKI_SIG_RSA_SHA224
PKI_SIG_RSA_SHA256
PKI_SIG_RSA_SHA384
PKI_SIG_RSA_SHA512
PKI_SIG_RSA_MD5
PKI_SIG_RSA_PSS_SHA1
PKI_SIG_RSA_PSS_SHA224
PKI_SIG_RSA_PSS_SHA256
PKI_SIG_RSA_PSS_SHA384
PKI_SIG_RSA_PSS_SHA512
PKI_SIG_ECDSA_SHA1
PKI_SIG_ECDSA_SHA224
PKI_SIG_ECDSA_SHA256
PKI_SIG_ECDSA_SHA384
PKI_SIG_ECDSA_SHA512
PKI_SIG_ED25519
PKI_SIG_ED448
```

and optionally add any of the following:

```

PKI_CMS_EXCLUDE_CERTS
PKI_CMS_EXCLUDE_DATA
PKI_CMS_CERTS_ONLY
PKI_CMS_USE_SKI
PKI_CMS_INCLUDE_ATTRS
PKI_CMS_FORMAT_BASE64
PKI_CMS_NO_OUTER
PKI_CMS_ALT_ALGID
PKI_CMS_BIGFILE
PKI_PSS_SALTLEN_ZERO
PKI_MGF_MGF1SHA1
PKI_CMS_ADD_SIGNER
```

If the `PKI_CMS_INCLUDE_ATTRS` option flag is included, optionally add any of the following:

```

PKI_CMS_ADD_SIGNTIME
PKI_CMS_ADD_SMIMECAP
PKI_CMS_ADD_SIGNINGCERT
PKI_CMS_ADD_ALGPROTECT
```

#### Return Value

`Long:` Zero on success else a nonzero error code.

---

### <a id="VB_cmsMakeSigDataFromBytes"></a>cmsMakeSigDataFromBytes

Create a CMS signed-data object from data in a byte array.

#### Syntax

[VBA]

```

Public Function cmsMakeSigDataFromBytes ( _
    szFileOut As String, _
    lpInput() As Byte, _
    szCertList As String, _
    szPrivateKey As String, _
    Optional nOptions As Long = 0 _
) As Long

```

#### Parameters

szFileOut

:   Name of output file to be created.

lpInput

:   Input data.

szCertList

:   Filename of the signer's certificate (or a string with its base64 or PEM representation)
and (optionally) a list of other certificates to be included in the output, separated by semi-colons (;)
Alternatively, specify a single PKCS#7 certificate chain file (.p7c/.p7b) containing the signer's certificate.

szPrivateKey

:   Internal representation of private key for the sender.

nOptions

:   Select the signature algorithm from one of:

```

PKI_SIG_RSA_SHA1
PKI_SIG_RSA_SHA224
PKI_SIG_RSA_SHA256
PKI_SIG_RSA_SHA384
PKI_SIG_RSA_SHA512
PKI_SIG_RSA_MD5
PKI_SIG_RSA_PSS_SHA1
PKI_SIG_RSA_PSS_SHA224
PKI_SIG_RSA_PSS_SHA256
PKI_SIG_RSA_PSS_SHA384
PKI_SIG_RSA_PSS_SHA512
PKI_SIG_ECDSA_SHA1
PKI_SIG_ECDSA_SHA224
PKI_SIG_ECDSA_SHA256
PKI_SIG_ECDSA_SHA384
PKI_SIG_ECDSA_SHA512
PKI_SIG_ED25519
PKI_SIG_ED448
```

and optionally add any of the following:

```

PKI_CMS_EXCLUDE_CERTS
PKI_CMS_EXCLUDE_DATA
PKI_CMS_CERTS_ONLY
PKI_CMS_USE_SKI
PKI_CMS_INCLUDE_ATTRS
PKI_CMS_FORMAT_BASE64
PKI_CMS_NO_OUTER
PKI_CMS_ALT_ALGID
PKI_CMS_BIGFILE
PKI_PSS_SALTLEN_ZERO
PKI_MGF_MGF1SHA1
PKI_CMS_ADD_SIGNER
```

If the `PKI_CMS_INCLUDE_ATTRS` option flag is included, optionally add any of the following:

```

PKI_CMS_ADD_SIGNTIME
PKI_CMS_ADD_SMIMECAP
PKI_CMS_ADD_SIGNINGCERT
PKI_CMS_ADD_ALGPROTECT
```

#### Return Value

`Long:` Zero on success else a nonzero error code.

---

### <a id="VB_cmsMakeSigDataFromSigValue"></a>cmsMakeSigDataFromSigValue

Create a CMS signed-data object using a pre-computed signature value.

#### Syntax

[VBA]

```

Public Function cmsMakeSigDataFromSigValue ( _
    szFileOut As String, _
    lpSigValue() As Byte, _
    lpInput() As Byte, _
    szCertList As String, _
    Optional nOptions As Long = 0 _
) As Long

```

#### Parameters

szFileOut

:   Name of output file to be created.

lpSigValue

:   Pre-computed signature value in byte array.

lpInput

:   Input data.

szCertList

:   Filename of the signer's certificate (or a string with its base64 or PEM representation)
and (optionally) a list of other certificates to be included in the output, separated by semi-colons (;)
Alternatively, specify a single PKCS#7 certificate chain file (.p7c/.p7b) containing the signer's certificate.

nOptions

:   Select the signature algorithm from one of:

```

PKI_SIG_RSA_SHA1
PKI_SIG_RSA_SHA224
PKI_SIG_RSA_SHA256
PKI_SIG_RSA_SHA384
PKI_SIG_RSA_SHA512
PKI_SIG_RSA_MD5
```

and optionally add any of the following:

```

PKI_CMS_EXCLUDE_CERTS
PKI_CMS_FORMAT_BASE64
PKI_CMS_NO_OUTER
PKI_CMS_ALT_ALGID
PKI_CMS_PSEUDOSIG
```

#### Return Value

`Long:` Zero on success else a nonzero error code.

#### Remarks

Specialised option for a specific case where the RSA v1.5 signature value over the content has been computed separately.
RSASSA-PKCS-v1_5 only.

---

### <a id="VB_cmsMakeSigDataFromString"></a>cmsMakeSigDataFromString

Create a CMS signed-data object from data in a string.

#### Syntax

[VBA]

```

Public Function cmsMakeSigDataFromString ( _
    szFileOut As String, _
    szDataIn As String, _
    szCertList As String, _
    szPrivateKey As String, _
    Optional nOptions As Long = 0 _
) As Long

```

#### Parameters

szFileOut

:   Name of output file to be created.

szDataIn

:   String containing message data to be signed.

szCertList

:   Filename of the signer's certificate (or a string with its base64 or PEM representation)
and (optionally) a list of other certificates to be included in the output, separated by semi-colons (;)
Alternatively, specify a single PKCS#7 certificate chain file (.p7c/.p7b) containing the signer's certificate.

szPrivateKey

:   Internal representation of private key for the sender.

nOptions

:   Select the signature algorithm from one of:

```

PKI_SIG_RSA_SHA1
PKI_SIG_RSA_SHA224
PKI_SIG_RSA_SHA256
PKI_SIG_RSA_SHA384
PKI_SIG_RSA_SHA512
PKI_SIG_RSA_MD5
PKI_SIG_RSA_PSS_SHA1
PKI_SIG_RSA_PSS_SHA224
PKI_SIG_RSA_PSS_SHA256
PKI_SIG_RSA_PSS_SHA384
PKI_SIG_RSA_PSS_SHA512
PKI_SIG_ECDSA_SHA1
PKI_SIG_ECDSA_SHA224
PKI_SIG_ECDSA_SHA256
PKI_SIG_ECDSA_SHA384
PKI_SIG_ECDSA_SHA512
PKI_SIG_ED25519
PKI_SIG_ED448
```

and optionally add any of the following:

```

PKI_CMS_EXCLUDE_CERTS
PKI_CMS_EXCLUDE_DATA
PKI_CMS_CERTS_ONLY
PKI_CMS_USE_SKI
PKI_CMS_INCLUDE_ATTRS
PKI_CMS_FORMAT_BASE64
PKI_CMS_NO_OUTER
PKI_CMS_ALT_ALGID
PKI_CMS_BIGFILE
PKI_PSS_SALTLEN_ZERO
PKI_MGF_MGF1SHA1
PKI_CMS_ADD_SIGNER
```

If the `PKI_CMS_INCLUDE_ATTRS` option flag is included, optionally add any of the following:

```

PKI_CMS_ADD_SIGNTIME
PKI_CMS_ADD_SMIMECAP
PKI_CMS_ADD_SIGNINGCERT
PKI_CMS_ADD_ALGPROTECT
```

#### Return Value

`Long:` Zero on success else a nonzero error code.

---

### <a id="VB_cmsQueryEnvData"></a>cmsQueryEnvData

Query a CMS enveloped-data object file for selected information.

#### Syntax

[VBA]

```

Public Function cmsQueryEnvData ( _
    szFileIn As String, _
    szQuery As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szFileIn

:   Name of file containing CMS enveloped-data object (binary or base64-encoded) or the data as a base64 or PEM string.

szQuery

:   Query string (case insensitive). Valid queries are:

```

"version"
"recipientInfoVersion"
"recipientInfoType"
"CountOfRecipientInfos"
"recipientIssuerName"
"recipientSerialNumber"
"keyEncryptionAlgorithm"
"keyEncryptionFlags"
"SizeofEncryptedKey"
"encryptedKey"
"oaepParams"
"kemParams"
"keyWrapAlgorithm"
"originatorKeyAlgorithm"
"originatorPublicKey"
"keyid"
"ukm"
"contentEncryptionAlgorithm"
"SizeofEncryptedContent"
"encryptedContent"
"iv"
"HASsubjectKeyIndentifier"
"recipientIdentifier"
```

nOptions

:   For future use.

#### Return Value

`String:` String containing the result or an empty string if not found or error.

#### Remarks

By default, the function queries the first recipientInfo in the file. To query the nth recipientInfo append "/n" to the query string,
e.g. `"recipientInfoVersion/2"` to find the version number of the second recipientInfo in the file.

---

### <a id="VB_cmsQuerySigData"></a>cmsQuerySigData

Query a CMS signed-data object file for selected information.

#### Syntax

[VBA]

```

Public Function cmsQuerySigData ( _
    szFileIn As String, _
    szQuery As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szFileIn

:   Name of file containing CMS signed-data object (binary or base64-encoded) or the data as a base64 or PEM string.

szQuery

:   Query string (case insensitive). Valid queries are:

```

"version"
"eContentType"
"HASeContent"
"CountOfCertificates"
"CountOfSignerInfos"
"CountOfDigestAlgs"
"certificate/N"
"signerInfoVersion"
"digestAlgorithm"
"signatureAlgorithm"
"HASsignedAttributes"
"signingTime"
"messageDigest"
"pssParams"
"HASsigningCertificate"
"HASalgorithmProtection"
"HASsubjectKeyIndentifier"
"signerIdentifier"
```

nOptions

:   For future use.

#### Return Value

`String:` String containing the result or an empty string if not found or error.

#### Remarks

By default, the function queries the first signerInfo in the file. To query the nth signerInfo append "/n" to the query string,
e.g. `"signerInfoVersion/2"` to find the version number of the second signerInfo in the file.

---

### <a id="VB_cmsReadEnvDataToBytes"></a>cmsReadEnvDataToBytes

Read and decrypt a CMS enveloped-data object to a byte array.

#### Syntax

[VBA]

```

Public Function cmsReadEnvDataToBytes ( _
    szFileIn As String, _
    szCertFile As String, _
    szPrivateKey As String, _
    Optional nOptions As Long = 0 _
) As Byte()

```

#### Parameters

szFileIn

:   Name of file containing CMS enveloped-data object (binary or base64-encoded) or the data as a base64 or PEM string.

szCertFile

:   Filename of the recipient's X.509 certificate (optional).

szPrivateKey

:   Internal representation of private key.

nOptions

:   For future use.

#### Return Value

`Byte():` Decrypted content in a byte array, or empty array on error.

#### Remarks

Use this if the content contains non-ASCII characters, e.g. UTF-8 encoded.

---

### <a id="VB_cmsReadEnvDataToString"></a>cmsReadEnvDataToString

Read and decrypt a CMS enveloped-data object to a string.

#### Syntax

[VBA]

```

Public Function cmsReadEnvDataToString ( _
    szFileIn As String, _
    szCertFile As String, _
    szPrivateKey As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szFileIn

:   Name of file containing CMS enveloped-data object (binary or base64-encoded) or the data as a base64 or PEM string.

szCertFile

:   Filename of the recipient's X.509 certificate (optional).

szPrivateKey

:   Internal representation of private key.

nOptions

:   For future use.

#### Return Value

`String:` Decrypted content in a string or empty string on error.

#### Remarks

Use this only when the decrypted text is known to be plain ASCII text, otherwise use `cmsReadEnvDataToBytes()`.

---

### <a id="VB_cmsReadSigDataToBytes"></a>cmsReadSigDataToBytes

Read the content from a CMS signed-data object directly into a byte array.

#### Syntax

[VBA]

```

Public Function cmsReadSigDataToBytes ( _
    szFileIn As String, _
    Optional nOptions As Long = 0 _
) As Byte()

```

#### Parameters

szFileIn

:   Name of file containing CMS signed-data object (binary or base64-encoded) or the data as a base64 or PEM string.

nOptions

:   For future use.

#### Return Value

`Byte():` Byte array containing the content or a zero-length array if error.

#### Remarks

Use this if the content contains non-ASCII characters, e.g. UTF-8 encoded.

---

### <a id="VB_cmsReadSigDataToString"></a>cmsReadSigDataToString

Read the content from a CMS signed-data object directly into a string.

#### Syntax

[VBA]

```

Public Function cmsReadSigDataToString ( _
    szFileIn As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szFileIn

:   Name of file containing CMS signed-data object (binary or base64-encoded) or the data as a base64 or PEM string.

nOptions

:   For future use.

#### Return Value

`String:` String containing the content or an empty string on error.

#### Remarks

Use this only if the content is known to be plain ASCII text, otherwise use `cmsReadSigDataToBytes()`.

---

### <a id="VB_cmsVerifySigData"></a>cmsVerifySigData

Verify the signature and content of a signed-data CMS object file.

#### Syntax

[VBA]

```

Public Function cmsVerifySigData ( _
    szFileIn As String, _
    Optional szCertFile As String = "", _
    Optional szHexDigest As String = "", _
    Optional nOptions As Long = 0 _
) As Long

```

#### Parameters

szFileIn

:   Name of file containing CMS signed-data object (binary or base64-encoded) or the data as a base64 or PEM string.

szCertFile

:   (optional) X.509 certificate file of the signer.

szHexDigest

:   (optional) digest of eContent to be verified (use for "detached-signature" form)

nOptions

:   Add to speed up the processing of large files (binary input only).

```

PKI_CMS_BIGFILE
```

#### Return Value

`Long:` Zero on success; otherwise a nonzero error code.

---

### <a id="VB_cnvB64Filter"></a>cnvB64Filter

Strip any invalid base64 characters from a string.

#### Syntax

[VBA]

```

Public Function cnvB64Filter ( _
    szB64 As String _
) As String

```

#### Parameters

szB64

:   String to be filtered.

#### Return Value

`String:` Filtered string.

---

### <a id="VB_cnvB64StrFromBytes"></a>cnvB64StrFromBytes

Encode an array of bytes as a base64-encoded string.

#### Syntax

[VBA]

```

Public Function cnvB64StrFromBytes ( _
    lpData() As Byte _
) As String

```

#### Parameters

lpData

:   Input byte array.

#### Return Value

`String:` Base64-encoded string.

#### Remarks

Same as [cnvToBase64](#VB_cnvToBase64).

---

### <a id="VB_cnvB64StrFromHexStr"></a>cnvB64StrFromHexStr

Re-encode a hexadecimal-encoded binary value as base64.

#### Syntax

[VBA]

```

Public Function cnvB64StrFromHexStr ( _
    szHex As String _
) As String

```

#### Parameters

szHex

:   Hex string representing a binary value.

#### Return Value

`String:` Binary value encoded in base64

---

### <a id="VB_cnvB64StrFromString"></a>cnvB64StrFromString

Encode an ANSI string as a base64-encoded string.

#### Syntax

[VBA]

```

Public Function cnvB64StrFromString ( _
    szData As String _
) As String

```

#### Parameters

szData

:   String to be encoded.

#### Return Value

`String:` Base64-encoded string.

#### Remarks

Expecting a string of 8-bit "ANSI" characters.

---

### <a id="VB_cnvBase58FromBytes"></a>cnvBase58FromBytes

Convert 8-bit binary data to equivalent base58-encoded string format.

#### Syntax

[VBA]

```

Public Function cnvBase58FromBytes ( _
    lpInput() As Byte _
) As String

```

#### Parameters

lpInput

:   Binary data.

#### Return Value

`String:` Base58-encoded string.

#### Remarks

This uses the "Bitcoin" scheme of base58 encoding where the leading character "1"
is reserved for representing an entire leading zero byte.

---

### <a id="VB_cnvBase58ToBytes"></a>cnvBase58ToBytes

Convert a base58-encoded string to an equivalent array of 8-bit unsigned integers.

#### Syntax

[VBA]

```

Public Function cnvBase58ToBytes ( _
    szInput As String _
) As Byte()

```

#### Parameters

szInput

:   Base58-encoded data.

#### Return Value

`Byte():` Data as array of bytes.

#### Remarks

This uses the "Bitcoin" scheme of base58 encoding where the leading character "1"
is reserved for representing an entire leading zero byte.

---

### <a id="VB_cnvByteEncoding"></a>cnvByteEncoding

Convert encoding of byte array between UTF-8 and Latin-1.

#### Syntax

[VBA]

```

Public Function cnvByteEncoding ( _
    lpInput() As Byte, _
    nOptions As Long _
) As Byte()

```

#### Parameters

lpInput

:   Base58-encoded data.

nOptions

:   Option flags. Select one of:

```

PKI_CNV_UTF8_FROM_LATIN1
PKI_CNV_LATIN1_FROM_UTF8
```

#### Return Value

`Byte():` Converted data (or empty array on error).

---

### <a id="VB_cnvBytesFromB64Str"></a>cnvBytesFromB64Str

Decode a base64-encoded string as an array of Bytes.

#### Syntax

[VBA]

```

Public Function cnvBytesFromB64Str ( _
    szB64 As String _
) As Byte()

```

#### Parameters

szB64

:   Base64 data to be decoded.

#### Return Value

`Byte():` Binary data in byte array, or an empty array on error.

#### Remarks

Same as [cnvFromBase64](#VB_cnvFromBase64).

---

### <a id="VB_cnvBytesFromHexStr"></a>cnvBytesFromHexStr

Decode a hexadecimal-encoded string as an array of Bytes.

#### Syntax

[VBA]

```

Public Function cnvBytesFromHexStr ( _
    szHex As String _
) As Byte()

```

#### Parameters

szHex

:   Hexadecimal data to be decoded.

#### Return Value

`Byte():` Binary data in byte array, or an empty array on error.

#### Remarks

Same as [cnvFromHex](#VB_cnvFromHex).

---

### <a id="VB_cnvBytesLen"></a>cnvBytesLen

Find length of byte array.

#### Syntax

[VBA]

```

Public Function cnvBytesLen ( _
    ab() As Byte _
) As Long

```

#### Parameters

ab

:   Input byte array.

#### Return Value

`Long:` Number of bytes in array.

#### Remarks

Safe to use even if array is empty.

#### Example

```

Dim ab() As Byte
Debug.Print cnvBytesLen(ab) ' Expecting 0
ReDim ab(10)    ' NB actually 11 elements (0..10)
Debug.Print cnvBytesLen(ab) ' 11
ab = vbNullString   ' Set to empty array
Debug.Print cnvBytesLen(ab) ' 0
```

---

### <a id="VB_cnvBytesMid"></a>cnvBytesMid

Return a substring of bytes of specified length from within a given byte array

#### Syntax

[VBA]

```

Public Function cnvBytesMid ( _
    Bytes() As Byte, _
    nOffset As Long, _
    Optional nBytes As Long = -1 _
) As Byte()

```

#### Parameters

Bytes

:   Byte array from which to return a substring (of bytes)

nOffset

:   Offset at which substring begins. First byte is at offset zero.

nBytes

:   Number of bytes in substring (optional). If negative, copy to end of input.

#### Return Value

`Byte():` A byte array containing a specified number of bytes from a byte array.

---

### <a id="VB_cnvCheckUTF8Bytes"></a>cnvCheckUTF8Bytes

Check if a byte array contains valid UTF-8 characters.

#### Syntax

[VBA]

```

Public Function cnvCheckUTF8Bytes ( _
    lpInput() As Byte _
) As Long

```

#### Parameters

lpInput

:   data to be checked

#### Return Value

`Long:` Zero if the data is invalid UTF-8, or a positive number (1-3) if the input contains valid UTF-8 data.

#### Remarks

The return value indicates the nature of the encoded characters:

```

0 = Not valid UTF-8
1 = Valid UTF-8, all chars are 7-bit ASCII
2 = Valid UTF-8, contains at least one multi-byte character equivalent to 8-bit ANSI
3 = Valid UTF-8, contains at least one multi-byte character that cannot be represented in a single-byte character set
```

---

### <a id="VB_cnvFromBase64"></a>cnvFromBase64

Decodes a base64-encoded string as an array of bytes.

#### Syntax

[VBA]

```

Public Function cnvFromBase64 ( _
    strBase64 As String _
) As Byte()

```

#### Parameters

strBase64

:   Base64 data to be decoded.

#### Return Value

`Byte():` Array of bytes.

#### Remarks

A shorter synonym for [cnvBytesFromB64Str](#VB_cnvBytesFromB64Str)

---

### <a id="VB_cnvFromHex"></a>cnvFromHex

Decodes a hexadecimal-encoded string as an array of bytes.

#### Syntax

[VBA]

```

Public Function cnvFromHex ( _
    strHex As String _
) As Byte()

```

#### Parameters

strHex

:   Hexadecimal-encoded data to be decoded.

#### Return Value

`Byte():` Array of bytes.

#### Remarks

A shorter synonym for [cnvBytesFromHexStr](#VB_cnvBytesFromHexStr)

---

### <a id="VB_cnvHexFilter"></a>cnvHexFilter

Strip any invalid hex characters from a hex string.

#### Syntax

[VBA]

```

Public Function cnvHexFilter ( _
    szHex As String _
) As String

```

#### Parameters

szHex

:   String to be filtered.

#### Return Value

`String:` Filtered string.

---

### <a id="VB_cnvHexFromBytesMid"></a>cnvHexFromBytesMid

Encode a substring of an array of bytes as a hexadecimal-encoded string.

#### Syntax

[VBA]

```

Public Function cnvHexFromBytesMid ( _
    abData() As Byte, _
    nOffset As Long, _
    nBytes As Long _
) As String

```

#### Parameters

abData

:   Input byte array.

nOffset

:   Offset at which substring begins. First byte is at offset zero.

nBytes

:   Number of bytes in substring to encode.

#### Return Value

`String:` Hexadecimal-encoded string.

#### Example

```

Debug.Print cnvHexFromBytesMid(cnvBytesFromHexStr("00112233445566"), 3, 2) ' 3344
```

---

### <a id="VB_cnvHexStrFromB64Str"></a>cnvHexStrFromB64Str

Re-encode a base64-encoded binary value as hexadecimal.

#### Syntax

[VBA]

```

Public Function cnvHexStrFromB64Str ( _
    szB64 As String _
) As String

```

#### Parameters

szB64

:   Base64 string representing a binary value.

#### Return Value

`String:` Binary value encoded in hexadecimal

---

### <a id="VB_cnvHexStrFromBytes"></a>cnvHexStrFromBytes

Encode an array of bytes as a hexadecimal-encoded string.

#### Syntax

[VBA]

```

Public Function cnvHexStrFromBytes ( _
    lpData() As Byte _
) As String

```

#### Parameters

lpData

:   Input byte array.

#### Return Value

`String:` Hexadecimal-encoded string.

#### Remarks

Same as [cnvToHex](#VB_cnvToHex).

---

### <a id="VB_cnvHexStrFromString"></a>cnvHexStrFromString

Encode an ANSI string as a hexadecimal-encoded string.

#### Syntax

[VBA]

```

Public Function cnvHexStrFromString ( _
    szData As String _
) As String

```

#### Parameters

szData

:   String to be encoded.

#### Return Value

`String:` Hexadecimal-encoded string.

#### Remarks

Expecting a string of 8-bit "ANSI" characters.

---

### <a id="VB_cnvLatin1FromUTF8Bytes"></a>cnvLatin1FromUTF8Bytes

Convert UTF-8 encoded array of bytes into a Latin-1 string, if possible.

#### Syntax

[VBA]

```

Public Function cnvLatin1FromUTF8Bytes ( _
    lpInput() As Byte _
) As String

```

#### Parameters

lpInput

:   Array containing UTF-8 encoded data.

#### Return Value

`String:` Decoded bytes in a VBA Unicode string.

---

### <a id="VB_cnvNumFromBytes"></a>cnvNumFromBytes

Convert the leftmost four bytes of an array to a 32-bit integer.

#### Syntax

[VBA]

```

Public Function cnvNumFromBytes ( _
    lpInput() As Byte, _
    Optional nOptions As Long = 0 _
) As Long

```

#### Parameters

lpInput

:   Byte array to be converted.

nOptions

:   Option flags. Use 0 for default big-endian order or one of:

```

PKI_CNV_BIG_ENDIAN (0)
PKI_CNV_LITTLE_ENDIAN
```

#### Return Value

`Long:` Decoded integer value.

#### Remarks

An array shorter than 4 bytes will be padded on the right with zeros.

#### Example

```

Debug.Print Hex(cnvNumFromBytes(cnvFromHex("DEADBEEF")))
'DEADBEEF
Debug.Print cnvNumFromBytes(cnvFromHex("DEADBEEF"))
'-559038737
```

---

### <a id="VB_cnvNumToBytes"></a>cnvNumToBytes

Convert a 32-bit integer to an array of 4 bytes.

#### Syntax

[VBA]

```

Public Function cnvNumToBytes ( _
    nNumber As Long, _
    Optional nOptions As Long = 0 _
) As Byte()

```

#### Parameters

nNumber

:   Integer to be converted.

nOptions

:   Option flags. Use 0 for default big-endian order or one of:

```

PKI_CNV_BIG_ENDIAN (0)
PKI_CNV_LITTLE_ENDIAN
```

#### Return Value

`Byte():` Byte array containing representation of integer in given order.

#### Example

```

Debug.Print cnvToHex(cnvNumToBytes(&HDEADBEEF, PKI_CNV_LITTLE_ENDIAN))
'EFBEADDE
```

---

### <a id="VB_cnvReverseBytes"></a>cnvReverseBytes

Reverse the order of a byte array.

#### Syntax

[VBA]

```

Public Function cnvReverseBytes ( _
    lpInput() As Byte _
) As Byte()

```

#### Parameters

lpInput

:   Input data to be reversed.

#### Return Value

`Byte():` Byte array in reverse order.

#### Example

```

Debug.Print cnvToHex(cnvReverseBytes(cnvFromHex("DEADBEEF")))
'EFBEADDE
```

---

### <a id="VB_cnvStringFromHexStr"></a>cnvStringFromHexStr

Decode a hexadecimal-encoded string as an ANSI string.

#### Syntax

[VBA]

```

Public Function cnvStringFromHexStr ( _
    ByVal szHex As String _
) As String

```

#### Parameters

szHex

:   Hexadecimal data to be decoded.

#### Return Value

`String:` Decoded string. For example, "6162632E" will be converted to "abc."

#### Remarks

Output is a string of "ANSI" characters of value between 0 and 255.

---

### <a id="VB_cnvToBase64"></a>cnvToBase64

Encodes an array of bytes as a base64-encoded string.

#### Syntax

[VBA]

```

Public Function cnvToBase64 ( _
    lpData() As Byte _
) As String

```

#### Parameters

lpData

:   Input byte array

#### Return Value

`String:` Base64-encoded string

#### Remarks

A shorter synonym for [cnvB64StrFromBytes](#VB_cnvB64StrFromBytes)

---

### <a id="VB_cnvToHex"></a>cnvToHex

Encodes an array of bytes as a hexadecimal-encoded string.

#### Syntax

[VBA]

```

Public Function cnvToHex ( _
    lpData() As Byte _
) As String

```

#### Parameters

lpData

:   Input byte array

#### Return Value

`String:` Hexadecimal-encoded string

#### Remarks

A shorter synonym for [cnvHexStrFromBytes](#VB_cnvHexStrFromBytes)

---

### <a id="VB_cnvUTF8BytesFromLatin1"></a>cnvUTF8BytesFromLatin1

Convert a string of 8-bit Latin-1 (ISO-8859-1) characters into a UTF-8 encoded array of bytes.

#### Syntax

[VBA]

```

Public Function cnvUTF8BytesFromLatin1 ( _
    szInput As String _
) As Byte()

```

#### Parameters

szInput

:   String of Latin-1 characters to be converted.

#### Return Value

`Byte():` UTF-8 encoded sequence of bytes.

---

### <a id="VB_comprCompress"></a>comprCompress

Compress data using zlib compression.

#### Syntax

[VBA]

```

Public Function comprCompress ( _
    lpInput() As Byte, _
    Optional nOptions As Long = 0 _
) As Byte()

```

#### Parameters

lpInput

:   Data to be compressed.

nOptions

:   For future use.

#### Return Value

`Byte():` Compressed data, or an empty array on error.

---

### <a id="VB_comprUncompress"></a>comprUncompress

Uncompress data using zlib compression.

#### Syntax

[VBA]

```

Public Function comprUncompress ( _
    lpInput() As Byte, _
    Optional nOptions As Long = 0 _
) As Byte()

```

#### Parameters

lpInput

:   Data to be uncompressed.

nOptions

:   For future use.

#### Return Value

`Byte():` Uncompressed data, or an empty array on error.

---

### <a id="VB_eccDHSharedSecret"></a>eccDHSharedSecret

Compute EC Diffie-Hellman (ECDH) shared secret.

#### Syntax

[VBA]

```

Public Function eccDHSharedSecret ( _
    szIntPrivateKey As String, _
    szIntPublicKey As String, _
    Optional nOptions As Long = 0 _
) As Byte()

```

#### Parameters

szIntPrivateKey

:   String containing our own private key in ephemeral "internal" form.

szIntPublicKey

:   String containing other party's public key in "internal" form.

nOptions

:   For future use.

#### Return Value

`Byte():` The Diffie-Hellman shared secret, or an empty array on error.

---

### <a id="VB_eccKeyHashCode"></a>eccKeyHashCode

Compute the hash code of an "internal" ECC public or private key string.

#### Syntax

[VBA]

```

Public Function eccKeyHashCode ( _
    szIntKeyString As String _
) As Long

```

#### Parameters

szIntKeyString

:   Key in ephemeral "internal" representation.

#### Return Value

`Long:` A 32-bit hash code for the key, or zero on error.

#### Remarks

Should be the same for a matching private and public key.

---

### <a id="VB_eccMakeKeys"></a>eccMakeKeys

Generate an EC public/private key pair and save as two key files.

#### Syntax

[VBA]

```

Public Function eccMakeKeys ( _
    szPubKeyFile As String, _
    szPriKeyFile As String, _
    szCurveName As String, _
    szPassword As String, _
    Optional szParams As String = "", _
    Optional nOptions As Long = 0 _
) As Long

```

#### Parameters

szPubKeyFile

:   Output filename for public key.

szPriKeyFile

:   Output filename for (encrypted) private key.

szCurveName

:   Name of elliptic curve

szPassword

:   Password for encrypted private key (required).

szParams

:   Optional parameters. A set of attribute name=value pairs separated by a semicolon ";" (see remarks).

nOptions

:   Use 0 for defaults.
  

A flag to indicate the password-based encryption scheme to be used to encrypt the private key file. Select from:

```

PKI_PBE_SHA_3DES (0) for "pbeWithSHAAnd3-KeyTripleDES-CBC" from PKCS12 (default)
PKI_PBE_PBKDF2_DESEDE3 for PBKDF2 using des-EDE3-CBC
PKI_PBE_PBKDF2_AES128 for PBKDF2 using aes128-CBC
PKI_PBE_PBKDF2_AES192 for PBKDF2 using aes192-CBC
PKI_PBE_PBKDF2_AES256 for PBKDF2 using aes256-CBC
```

plus optionally to output in textual PEM format [default format=DER binary]

```

PKI_KEY_FORMAT_PEM
```

#### Return Value

`Long:` Zero on success.

#### Remarks

Valid name-value pair parameters for `szParams` are:  

**count**=*integer* : To set the iteration count used in the PBKDF2 method, e.g. `"count=5000;"` [default=2048].  

**prf**=*hmac-name* : To change the HMAC algorithm used in the PBKDF2 method, e.g. `"prf=hmacWithSHA256;"` [default=`hmacWithSHA1`].  

**rngseed**=*string* : To add some user-supplied entropy for the key generation process, e.g. `"rngseed=pqrrr1234xyz;"`.  

Valid values for *hmac-name* are `{hmacWithSHA1|hmacWithSHA224|hmacWithSHA256|hmacWithSHA384|hmacWithSHA512}`.

#### Example

```

' Create an ECC key pair using defaults
r = eccMakeKeys("myeccP256.pub", "myeccP256.p8e", "Secp256r1", "password")
' Same but using different curve, stronger security and in PEM format
r = eccMakeKeys("myeccBP256r1.pub", "myeccBP256r1.p8e", "brainpoolP256r1", "password1", "count=6000;prf=hmacWithSHA256", PKI_PBE_PBKDF2_AES128 Or PKI_KEY_FORMAT_PEM)
```

---

### <a id="VB_eccPublicKeyFromPrivate"></a>eccPublicKeyFromPrivate

Convert an internal EC private key string into an internal EC public key string.

#### Syntax

[VBA]

```

Public Function eccPublicKeyFromPrivate ( _
    szIntKeyString As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szIntKeyString

:   Private key in ephemeral "internal" representation.

nOptions

:   For future use.

#### Return Value

`String:` Public key in ephemeral "internal" representation, or empty string on error.

---

### <a id="VB_eccQueryKey"></a>eccQueryKey

Query an EC key string for selected information.

#### Syntax

[VBA]

```

Public Function eccQueryKey ( _
    szIntKeyString As String, _
    szQuery As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szIntKeyString

:   Key in ephemeral "internal" representation.

szQuery

:   Query string (case insensitive). Valid queries are:

```

curveName
keyBits
isPrivate
privateKey
publicKey
```

nOptions

:   For future use.

#### Return Value

`String:` String containing the result or an empty string if not found or error.

---

### <a id="VB_eccReadKeyByCurve"></a>eccReadKeyByCurve

Read an EC key from its hexadecimal representation.

#### Syntax

[VBA]

```

Public Function eccReadKeyByCurve ( _
    szHexKey As String, _
    szCurveName As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szHexKey

:   Hexadecimal representation of the key, private or public.

szCurveName

:   Name of the elliptic curve.

nOptions

:   For **Safe Curves** specify `PKI_ECC_PRIVATE_KEY` or `PKI_ECC_PUBLIC_KEY` to indicate that the key value
represents a private or public key, respectively. Otherwise, `nOptions` is ignored.

#### Return Value

`String:` The key in ephemeral "internal" representation, or empty string on error.

---

### <a id="VB_eccReadPrivateKey"></a>eccReadPrivateKey

Read an EC private key from a file into an internal key string.

#### Syntax

[VBA]

```

Public Function eccReadPrivateKey ( _
    szKeyFileOrString As String, _
    Optional szPassword As String = "", _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szKeyFileOrString

:   Either the name of file containing the key or a string containing the key in PEM format.

szPassword

:   Password for the key file, if encrypted; otherwise set as `""`.

nOptions

:   For future use.

#### Return Value

`String:` String containing an internal representation of the private key, or empty string on error.

---

### <a id="VB_eccReadPublicKey"></a>eccReadPublicKey

Read an EC private key from a file into an internal key string.

#### Syntax

[VBA]

```

Public Function eccReadPublicKey ( _
    szKeyFileOrString As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szKeyFileOrString

:   Either the name of file containing the key or a string containing the key in PEM format.

nOptions

:   For future use.

#### Return Value

`String:` String containing an internal representation of the public key, or empty string on error.

---

### <a id="VB_eccSaveEncKey"></a>eccSaveEncKey

Save an internal EC private key string to an encrypted key file.

#### Syntax

[VBA]

```

Public Function eccSaveEncKey ( _
    szOutputFile As String, _
    szKeyStr As String, _
    szPassword As String, _
    Optional szParams As String = "", _
    Optional nOptions As Long = 0 _
) As Long

```

#### Parameters

szOutputFile

:   Name of output file to be created.

szKeyStr

:   The private key in an internal key string.

szPassword

:   Password for encrypted private key (required).

szParams

:   Optional parameters. A set of attribute name=value pairs separated by a semicolon ";" (see remarks).

nOptions

:   Use 0 for defaults.
  

A flag to indicate the password-based encryption scheme to be used to encrypt the private key file. Select from:

```

PKI_PBE_SHA_3DES (0) for "pbeWithSHAAnd3-KeyTripleDES-CBC" from PKCS12 (default)
PKI_PBE_PBKDF2_DESEDE3 for PBKDF2 using des-EDE3-CBC
PKI_PBE_PBKDF2_AES128 for PBKDF2 using aes128-CBC
PKI_PBE_PBKDF2_AES192 for PBKDF2 using aes192-CBC
PKI_PBE_PBKDF2_AES256 for PBKDF2 using aes256-CBC
```

plus optionally add the following to output in textual PEM format [default format=DER binary]

```

PKI_KEY_FORMAT_PEM
```

#### Return Value

`Long:` Zero on success else a nonzero error code.

#### Remarks

Valid name-value pair parameters for `szParams` are:  

**count**=*integer* : To set the iteration count used in the PBKDF2 method, e.g. `"count=5000;"` [default=2048].  

**prf**=*hmac-name* : To change the HMAC algorithm used in the PBKDF2 method, e.g. `"prf=hmacWithSHA256;"` [default=`hmacWithSHA1`].  

Valid values for *hmac-name* are `{hmacWithSHA1|hmacWithSHA224|hmacWithSHA256|hmacWithSHA384|hmacWithSHA512}`.

---

### <a id="VB_eccSaveKey"></a>eccSaveKey

Save an internal EC key string to a key file.

#### Syntax

[VBA]

```

Public Function eccSaveKey ( _
    szOutputFile As String, _
    szKeyStr As String, _
    Optional nOptions As Long = 0 _
) As Long

```

#### Parameters

szOutputFile

:   Name of output file to be created.

szKeyStr

:   Key string (public or private) in internal format.

nOptions

:   Choose one of

```

PKI_DEFAULT (0) to save the key in the default format.
PKI_KEY_TYPE_PKCS8 to save a NIST/SEC curve private key in PKCS#8 format.
```

and optionally add any of

```

PKI_KEY_FORMAT_PEM to save the key file in PEM form (default is binary DER-encoded format).
PKI_KEY_LEGACY to save a safe key in "legacy" PKCS#8 v1 format (default is v2 OneAsymmetricKey).
```

#### Return Value

`Long:` Zero on success else a nonzero error code.

#### Remarks

EC public keys are always saved in SubjectPublicKeyInfo format [RFC5480].
By default, NIST/SEC curve private keys are saved in ECPrivateKey format [RFC5915].
Use the `PKI_KEY_TYPE_PKCS8` option to save in PKCS#8 PrivateKeyInfo format [RFC5208].
Safe curve private keys (X25519, Ed25519, X448 and Ed448) are always saved in PKCS#8 v2
OneAsymmetricKey format including the public key [RFC5958]. Add the option `PKI_KEY_LEGACY`
to save in older PKCS#8 v1 PrivateKeyInfo format [RFC5208] excluding the public key.
To save a private key in encrypted form, use [eccSaveEncKey](#VB_eccSaveEncKey).

---

### <a id="VB_errFormatErrorMessage"></a>errFormatErrorMessage

Return an error message string for the last error.

#### Syntax

[VBA]

```

Public Function errFormatErrorMessage ( _
    Optional nErrCode As Long = 0, _
    Optional szMsg As String = "" _
) As String

```

#### Parameters

nErrCode

:   Error code returned by last function call (or zero if no code available).

szMsg

:   Optional message to add.

#### Return Value

`String:` Error message as a string including previous ErrorCode, if available.

#### Example

```

Debug.Print errFormatErrorMessage(11)
Error (11): Parameter out of range (OUT_OF_RANGE_ERROR)
Debug.Print errFormatErrorMessage(11, "User message!")
ERROR: User message! (11): Value out of range (OUT_OF_RANGE_ERROR)
```

---

### <a id="VB_hashBytes"></a>hashBytes

Compute hash digest in byte format of byte input.

#### Syntax

[VBA]

```

Public Function hashBytes ( _
    lpMessage() As Byte, _
    nOptions As Long _
) As Byte()

```

#### Parameters

lpMessage

:   Message to be digested in byte array.

nOptions

:   Algorithm to be used. Select one from:

```

PKI_HASH_SHA1
PKI_HASH_SHA224
PKI_HASH_SHA256
PKI_HASH_SHA384
PKI_HASH_SHA512
PKI_HASH_SHA3_224
PKI_HASH_SHA3_256
PKI_HASH_SHA3_384
PKI_HASH_SHA3_512
PKI_HASH_MD5
PKI_HASH_MD2
PKI_HASH_RMD160
PKI_HASH_BTC160
```

and optionally add `PKI_HASH_DOUBLE` to compute a double hash, `HASH(HASH(m))`.

#### Return Value

`Byte():` Message digest in byte array.

---

### <a id="VB_hashFile"></a>hashFile

Compute hash digest in byte format of a file.

#### Syntax

[VBA]

```

Public Function hashFile ( _
    szFileName As String, _
    nOptions As Long _
) As Byte()

```

#### Parameters

szFileName

:   Name of file containing message data.

nOptions

:   Algorithm to be used. Select one from:

```

PKI_HASH_SHA1
PKI_HASH_SHA224
PKI_HASH_SHA256
PKI_HASH_SHA384
PKI_HASH_SHA512
PKI_HASH_SHA3_224
PKI_HASH_SHA3_256
PKI_HASH_SHA3_384
PKI_HASH_SHA3_512
PKI_HASH_MD5
PKI_HASH_MD2
PKI_HASH_RMD160
PKI_HASH_BTC160
```

and optionally add `PKI_HASH_DOUBLE` to compute a double hash, `HASH(HASH(m))`.
Add `PKI_HASH_MODE_TEXT` to hash in "text" mode instead of default "binary" mode.

#### Return Value

`Byte():` Message digest in byte array.

#### Remarks

The default mode is "binary" where each byte is treated individually.
In "text" mode CR-LF pairs will be treated as a single newline (LF) character.

---

### <a id="VB_hashHexFromBytes"></a>hashHexFromBytes

Compute hash digest in hex format of byte input.

#### Syntax

[VBA]

```

Public Function hashHexFromBytes ( _
    lpMessage() As Byte, _
    nOptions As Long _
) As String

```

#### Parameters

lpMessage

:   Message to be digested in byte array.

nOptions

:   Algorithm to be used. Select one from:

```

PKI_HASH_SHA1
PKI_HASH_SHA224
PKI_HASH_SHA256
PKI_HASH_SHA384
PKI_HASH_SHA512
PKI_HASH_SHA3_224
PKI_HASH_SHA3_256
PKI_HASH_SHA3_384
PKI_HASH_SHA3_512
PKI_HASH_MD5
PKI_HASH_MD2
PKI_HASH_RMD160
PKI_HASH_BTC160
```

and optionally add `PKI_HASH_DOUBLE` to compute a double hash, `HASH(HASH(m))`.

#### Return Value

`String:` Message digest in hex-encoded format.

---

### <a id="VB_hashHexFromFile"></a>hashHexFromFile

Compute hash digest in hex format of a file.

#### Syntax

[VBA]

```

Public Function hashHexFromFile ( _
    szFileName As String, _
    nOptions As Long _
) As String

```

#### Parameters

szFileName

:   Name of file containing message data.

nOptions

:   Algorithm to be used. Select one from:

```

PKI_HASH_SHA1
PKI_HASH_SHA224
PKI_HASH_SHA256
PKI_HASH_SHA384
PKI_HASH_SHA512
PKI_HASH_SHA3_224
PKI_HASH_SHA3_256
PKI_HASH_SHA3_384
PKI_HASH_SHA3_512
PKI_HASH_MD5
PKI_HASH_MD2
PKI_HASH_RMD160
PKI_HASH_BTC160
```

and optionally add `PKI_HASH_DOUBLE` to compute a double hash, `HASH(HASH(m))`.
Add `PKI_HASH_MODE_TEXT` to hash in "text" mode instead of default "binary" mode.

#### Return Value

`String:` Message digest in hex-encoded format.

#### Remarks

The default mode is "binary" where each byte is treated individually.
In "text" mode CR-LF pairs will be treated as a single newline (LF) character.

---

### <a id="VB_hashHexFromHex"></a>hashHexFromHex

Compute hash digest in hex-encoded format from hex-encoded input.

#### Syntax

[VBA]

```

Public Function hashHexFromHex ( _
    szMsgHex As String, _
    nOptions As Long _
) As String

```

#### Parameters

szMsgHex

:   Message to be digested in hex-encoded format.

nOptions

:   Algorithm to be used. Select one from:

```

PKI_HASH_SHA1
PKI_HASH_SHA224
PKI_HASH_SHA256
PKI_HASH_SHA384
PKI_HASH_SHA512
PKI_HASH_SHA3_224
PKI_HASH_SHA3_256
PKI_HASH_SHA3_384
PKI_HASH_SHA3_512
PKI_HASH_MD5
PKI_HASH_MD2
PKI_HASH_RMD160
PKI_HASH_BTC160
```

and optionally add `PKI_HASH_DOUBLE` to compute a double hash, `HASH(HASH(m))`.

#### Return Value

`String:` Message digest in hex-encoded format.

---

### <a id="VB_hashLength"></a>hashLength

Return length of message digest output in bytes.

#### Syntax

[VBA]

```

Public Function hashLength ( _
    nAlgId As Long _
) As Long

```

#### Parameters

nAlgId

:   Algorithm Id flag. Select one of `PKI_HASH_*` or `PKI_HMAC_*`, for example:

```

PKI_HASH_SHA1
PKI_HASH_SHA224
PKI_HASH_SHA256
PKI_HASH_SHA384
PKI_HASH_SHA512
PKI_HASH_SHA3_224
PKI_HASH_SHA3_256
PKI_HASH_SHA3_384
PKI_HASH_SHA3_512
PKI_HASH_MD5
PKI_HASH_MD2
PKI_HASH_RMD160
PKI_HASH_BTC160
```

#### Return Value

`Long:` Length of the hash function output in bytes; else a negative error code.

#### Example

```

Debug.Print hashLength(PKI_HASH_SHA512)
64
```

---

### <a id="VB_hmacBytes"></a>hmacBytes

Compute hash-based message authentication code (HMAC) as a byte array from byte data.

#### Syntax

[VBA]

```

Public Function hmacBytes ( _
    lpMessage() As Byte, _
    lpKey() As Byte, _
    nOptions As Long _
) As Byte()

```

#### Parameters

lpMessage

:   Message to be signed in byte format.

lpKey

:   Key in byte format.

nOptions

:   Algorithm to be used. Select one from:

```

PKI_HMAC_SHA1
PKI_HMAC_SHA224
PKI_HMAC_SHA256
PKI_HMAC_SHA384
PKI_HMAC_SHA512
PKI_HMAC_SHA3_224
PKI_HMAC_SHA3_256
PKI_HMAC_SHA3_384
PKI_HMAC_SHA3_512
PKI_HMAC_MD5
```

#### Return Value

`Byte():` HMAC value in byte array.

---

### <a id="VB_hmacHexFromBytes"></a>hmacHexFromBytes

Compute hash-based message authentication code (HMAC) in hexadecimal format from byte data.

#### Syntax

[VBA]

```

Public Function hmacHexFromBytes ( _
    lpMessage() As Byte, _
    lpKey() As Byte, _
    nOptions As Long _
) As String

```

#### Parameters

lpMessage

:   Message to be signed in byte format.

lpKey

:   Key in byte format.

nOptions

:   Algorithm to be used. Select one from:

```

PKI_HMAC_SHA1
PKI_HMAC_SHA224
PKI_HMAC_SHA256
PKI_HMAC_SHA384
PKI_HMAC_SHA512
PKI_HMAC_SHA3_224
PKI_HMAC_SHA3_256
PKI_HMAC_SHA3_384
PKI_HMAC_SHA3_512
PKI_HMAC_MD5
```

#### Return Value

`String:` HMAC value in hex-encoded format.

---

### <a id="VB_hmacHexFromHex"></a>hmacHexFromHex

Compute hash-based message authentication code (HMAC) in hexadecimal format from data in hexadecimal-encoded strings.

#### Syntax

[VBA]

```

Public Function hmacHexFromHex ( _
    szMsgHex As String, _
    szKeyHex As String, _
    nOptions As Long _
) As String

```

#### Parameters

szMsgHex

:   Message to be signed in hex-encoded format.

szKeyHex

:   Key in hex-encoded format.

nOptions

:   Algorithm to be used. Select one from:

```

PKI_HMAC_SHA1
PKI_HMAC_SHA224
PKI_HMAC_SHA256
PKI_HMAC_SHA384
PKI_HMAC_SHA512
PKI_HMAC_SHA3_224
PKI_HMAC_SHA3_256
PKI_HMAC_SHA3_384
PKI_HMAC_SHA3_512
PKI_HMAC_MD5
```

#### Return Value

`String:` HMAC value in hex-encoded format.

---

### <a id="VB_hpkeDerivePrivateKey"></a>hpkeDerivePrivateKey

Derive an EC private key in a deterministic manner from input keying material using the DeriveKeyPair algorithm in RFC9180.

#### Syntax

[VBA]

```

Public Function hpkeDerivePrivateKey ( _
    lpIkm() As Byte, _
    szCurveName As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

lpIkm

:   Input key material (ikm). This *must* have length in bytes at least as long as the key to be produced.

szCurveName

:   ECDH curve name. Select one from

```
 "P-256" | "P-384" | "P-521" | "X25519" | "X448"
```

nOptions

:   Option flags. Select one of:
Zero (0) to output the private key in ephemeral "internal" key format (default);
or `PKI_ENCODE_HEX` to output the private key in serialized hex form.

#### Return Value

`String:` Derived private key in string form or an empty string on error.

#### Remarks

The KDF to be used is fixed by the EC curve group.
By default the key is output as an ephemeral "internal" key string, which can be used directly with
[eccSaveKey](#VB_eccSaveKey), [eccSaveEncKey](#VB_eccSaveEncKey), [eccPublicKeyFromPrivate](#VB_eccPublicKeyFromPrivate), [eccDHSharedSecret](#VB_eccDHSharedSecret) and [eccQueryKey](#VB_eccQueryKey).
If nOptions is set to `PKI_ENCODE_HEX` then the key is output in serialized hexadecimal form in the same manner
as the test vectors in [RFC9180] (without the clamping).

---

### <a id="VB_hpkeLabeledExpand"></a>hpkeLabeledExpand

Compute the output of the LabeledExpand function as defined in RFC9180.

#### Syntax

[VBA]

```

Public Function hpkeLabeledExpand ( _
    nBytes As Long, _
    lpPrk() As Byte, _
    szLabel As String, _
    lpInfo() As Byte, _
    szCurveName As String, _
    Optional nOptions As Long = 0 _
) As Byte()

```

#### Parameters

nBytes

:   Required number of bytes (L) of output keying material.

lpPrk

:   Pseudorandom key.

szLabel

:   Label string.

lpInfo

:   Byte string info.

szCurveName

:   Name of ECDH curve used in scheme. Specify one of:

```
 "P-256" | "P-384" | "P-521" | "X25519" | "X448"
```

nOptions

:   Use to specify the AEAD encryption algorithm used in the scheme (if applicable). Specify either:
Zero (0) to indicate that the KDF is being used inside a KEM algorithm
or, if used in the remainder of HPKE, one of:

```

PKI_AEAD_AES_128_GCM
PKI_AEAD_AES_256_GCM
PKI_AEAD_CHACHA20_POLY1305
```

#### Return Value

`Byte():` L bytes of output keying material.

#### Remarks

The ECDH curve group used in the scheme must be specified, which automatically fixes the KDF and associated HMAC algorithm to be used.

---

### <a id="VB_hpkeLabeledExtract"></a>hpkeLabeledExtract

Compute the output of the LabeledExtract function as defined in RFC9180.

#### Syntax

[VBA]

```

Public Function hpkeLabeledExtract ( _
    lpSalt() As Byte, _
    szLabel As String, _
    lpIkm() As Byte, _
    szCurveName As String, _
    Optional nOptions As Long = 0 _
) As Byte()

```

#### Parameters

lpSalt

:   Byte string salt.

szLabel

:   Label string.

lpIkm

:   Input keying material (ikm).

szCurveName

:   Name of ECDH curve used in scheme. Specify one of:

```
 "P-256" | "P-384" | "P-521" | "X25519" | "X448"
```

nOptions

:   Use to specify the AEAD encryption algorithm used in the scheme (if applicable). Specify either:
Zero (0) to indicate that the KDF is being used inside a KEM algorithm
or, if used in the remainder of HPKE, one of:

```

PKI_AEAD_AES_128_GCM
PKI_AEAD_AES_256_GCM
PKI_AEAD_CHACHA20_POLY1305
```

#### Return Value

`Byte():` A pseudorandom key of fixed length Nh bytes.

#### Remarks

This function outputs a fixed value of bytes equal to the length (Nh) of the underlying HMAC function used by the KDF algorithm.
The ECDH curve group used in the scheme must be specified, which automatically fixes the KDF and associated HMAC algorithm to be used.

---

### <a id="VB_kdfBytes"></a>kdfBytes

Generate a key-encryption key (KEK) from input keying material (IKM) using a key derivation function (KDF).

#### Syntax

[VBA]

```

Public Function kdfBytes ( _
    nKekBytes As Long, _
    lpIkm() As Byte, _
    lpInfo() As Byte, _
    Optional nOptions As Long = 0, _
    Optional szParams As String = "" _
) As Byte()

```

#### Parameters

nKekBytes

:   Required length of output key material in bytes.

lpIkm

:   Input key material/shared secret.

lpInfo

:   SharedInfo (optional, but a properly dimensioned variable must be passed, even if empty).

nOptions

:   Algorithm to be used. Select one from:

```

PKI_KDF_X963 (default)
PKI_KDF_HKDF
PKI_KDF_KDF2
PKI_KDF_KDF3
```

and select one hash algorithm to use with the key derivation function:

```

PKI_HASH_SHA1 (default)
PKI_HASH_SHA224
PKI_HASH_SHA256
PKI_HASH_SHA384
PKI_HASH_SHA512
```

szParams

:   Optional parameters. Set as `""` for defaults.
Use `salt=<hex-digits>` to set the optional salt parameter for the HKDF algorithm encoded in hex,
e.g. `"salt=606162636465666768696a6b6c6d6e6f;"`.

#### Return Value

`Byte():` Output key material (KEK) in a byte array.

#### Remarks

`PKI_KDF_X963` uses the ANSI-X9.63-KDF key derivation function.
`PKI_KDF_HKDF` uses the HMAC-based Key Derivation Function (HKDF) from RFC 5869.

#### Example

```

Dim lpKEK() As Byte
Dim lpZZ() As Byte
Dim lpInfo() As Byte
' ansx963_2001.rsp CAVS 12.0 'ANS X9.63-2001' information for sample
lpZZ = cnvFromHex("96c05619d56c328ab95fe84b18264b08725b85e33fd34f08")
lpKEK = kdfBytes(128 \ 8, lpZZ, lpInfo, PKI_HASH_SHA256)
Debug.Print "KEK = " & cnvToHex(lpKEK)
Debug.Print "OK  = 443024c3dae66b95e6f5670601558f71"
' [RFC 5869] A.1.  Test Case 1 Basic test case with SHA-256
lpZZ = cnvFromHex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b")
lpInfo = cnvFromHex("f0f1f2f3f4f5f6f7f8f9")
lpKEK = kdfBytes(42, lpZZ, lpInfo, PKI_KDF_HKDF Or PKI_HASH_SHA256, "salt=000102030405060708090a0b0c")
Debug.Print "KEK = " & cnvToHex(lpKEK)
Debug.Print "OK  = 3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"
```

---

### <a id="VB_kdfForCms"></a>kdfForCms

Generate a key-encryption key (KEK) for ECDH key exchange in a CMS EnvelopedData object.

#### Syntax

[VBA]

```

Public Function kdfForCms ( _
    lpZZ() As Byte, _
    lpUkm() As Byte, _
    Optional nOptions As Long = 0 _
) As Byte()

```

#### Parameters

lpZZ

:   Input key material/shared secret.

lpUkm

:   User key material (optional, but a properly dimensioned variable must be passed, even if empty).

nOptions

:   Algorithm to be used. Select one from:

```

PKI_KDF_X963 (default)
PKI_KDF_HKDF
```

and select one hash algorithm to use with the key derivation function:

```

PKI_HASH_SHA1 (default)
PKI_HASH_SHA224
PKI_HASH_SHA256
PKI_HASH_SHA384
PKI_HASH_SHA512
```

and select one key wrap algorithm (required, no default):

```

PKI_KWRAP_3DES
PKI_KWRAP_AES128
PKI_KWRAP_AES192
PKI_KWRAP_AES256
```

#### Return Value

`Byte():` Output key material (KEK) in a byte array.

#### Remarks

This is a specialist function using the key definition algorithms described in [RFC5753] and [RFC8418]
when used for key agreement with ECDH in a CMS EnvelopedData object using the ECC-CMS-SharedInfo structure.

#### Example

```

Dim lpKEK() As Byte
Dim lpZZ() As Byte
Dim lpUkm() As Byte
lpZZ = cnvFromHex("160E3F5588C6FB4E9CEE8BC3C1C5000AB86396468C3D1CAEC0CB6E21536B5513")
lpKEK = kdfForCms(lpZZ, lpUkm, PKI_KWRAP_AES128 Or PKI_KDF_X963 Or PKI_HASH_SHA1)
Debug.Print "KEK = " & cnvToHex(lpKEK)
Debug.Print "OK  = 04D616C654CDF62BB186A5A088B60FB5"
```

---

### <a id="VB_ocspMakeRequest"></a>ocspMakeRequest

Create an Online Certification Status Protocol (OCSP) request as a base64 string.

#### Syntax

[VBA]

```

Public Function ocspMakeRequest ( _
    szIssuerCert As String, _
    szCertFileOrSerialNum As String, _
    nOptions As Long, _
    Optional szExtensions As String = "" _
) As String

```

#### Parameters

szIssuerCert

:   Name of issuer's X.509 certificate file (or string with its base64 representation).

szCertFileOrSerialNum

:   Either the name of X.509 certificate file to be checked or its serial number in hexadecimal format preceded by `#x`.

nOptions

:   Algorithm to be used. Select one from:

```

PKI_HASH_SHA1
PKI_HASH_SHA224
PKI_HASH_SHA256
PKI_HASH_SHA384
PKI_HASH_SHA512
PKI_HASH_MD5
```

szExtensions

:   For future use.

#### Return Value

`String:` A base64 string suitable for an OCSP request to an Online Certificate Status Manager or an empty string on error.

#### Remarks

Note different order of parameters from core function.

---

### <a id="VB_ocspReadResponse"></a>ocspReadResponse

Read a response to an Online Certification Status Protocol (OCSP) request and outputs the main results in text form.

#### Syntax

[VBA]

```

Public Function ocspReadResponse ( _
    szResponseFile As String, _
    Optional szIssuerCert As String = "", _
    Optional nOptions As Long = 0, _
    Optional szExtensions As String = "" _
) As String

```

#### Parameters

szResponseFile

:   Name of the file containing the response data in BER format.

szIssuerCert

:   (optional) Name of issuer's X.509 certificate file (or string with its base64 representation).

nOptions

:   For future use.

szExtensions

:   For future use.

#### Return Value

`String:` A text string outlining the main results in the response data or an empty string on error.

#### Remarks

Note different order of parameters from core function.

---

### <a id="VB_padBytesBlock"></a>padBytesBlock

Creates an input block suitably padded for encryption by a block cipher in ECB or CBC mode.

#### Syntax

[VBA]

```

Public Function padBytesBlock ( _
    lpInput() As Byte, _
    nBlkLen As Long, _
    Optional nOptions As Long = 0 _
) As Byte()

```

#### Parameters

lpInput

:   Plaintext bytes to be padded.

nBlkLen

:   Cipher block length in bytes (8 or 16).

nOptions

:   Use 0 for default PKCS5 padding or select one of:

```

PKI_PAD_1ZERO
PKI_PAD_AX923
PKI_PAD_W3C
```

#### Return Value

`Byte():` Padded data in byte array.

---

### <a id="VB_padHexBlock"></a>padHexBlock

Creates a hex-encoded input block suitably padded for encryption by a block cipher in ECB or CBC mode.

#### Syntax

[VBA]

```

Public Function padHexBlock ( _
    szInput As String, _
    nBlkLen As Long, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szInput

:   Hexadecimal-encoded data to be padded.

nBlkLen

:   Cipher block length in bytes (8 or 16).

nOptions

:   Use 0 for default PKCS5 padding or select one of:

```

PKI_PAD_1ZERO
PKI_PAD_AX923
PKI_PAD_W3C
```

#### Return Value

`String:` Padded data in hex-encoded string.

---

### <a id="VB_padUnpadBytes"></a>padUnpadBytes

Removes the padding from an encryption block.

#### Syntax

[VBA]

```

Public Function padUnpadBytes ( _
    lpInput() As Byte, _
    nBlkLen As Long, _
    Optional nOptions As Long = 0 _
) As Byte()

```

#### Parameters

lpInput

:   Padded data.

nBlkLen

:   Cipher block length in bytes (8 or 16).

nOptions

:   Use 0 for default PKCS5 padding or select one of:

```

PKI_PAD_1ZERO
PKI_PAD_AX923
PKI_PAD_W3C
```

#### Return Value

`Byte():` Unpadded data in byte array or *unchanged* data on error.

#### Remarks

An error is indicated by returning the *original* data which will always be longer than the expected unpadded result.

---

### <a id="VB_padUnpadHex"></a>padUnpadHex

Removes the padding from a hex-encoded encryption block.

#### Syntax

[VBA]

```

Public Function padUnpadHex ( _
    szInput As String, _
    nBlkLen As Long, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szInput

:   Hex-encoded padded data.

nBlkLen

:   Cipher block length in bytes (8 or 16).

nOptions

:   Use 0 for default PKCS5 padding or select one of:

```

PKI_PAD_1ZERO
PKI_PAD_AX923
PKI_PAD_W3C
```

#### Return Value

`String:` Unpadded data in hex-encoded string or *unchanged* data on error.

#### Remarks

An error is indicated by returning the *original* data which will always be longer than the expected unpadded result.

---

### <a id="VB_pbeKdf2"></a>pbeKdf2

Derives a key of any length from a password using the PBKDF2 algorithm from PKCS#5 v2.1.

#### Syntax

[VBA]

```

Public Function pbeKdf2 ( _
    dkBytes As Long, _
    lpPwd() As Byte, _
    lpSalt() As Byte, _
    nCount As Long, _
    Optional nOptions As Long = 0 _
) As Byte()

```

#### Parameters

dkBytes

:   Required length of key in bytes.

lpPwd

:   Password encoded as byte array.

lpSalt

:   Salt in a byte array.

nCount

:   Iteration count.

nOptions

:   Hash algorithm to use in HMAC PRF. Select one from:

```

PKI_HMAC_SHA1
PKI_HMAC_SHA224
PKI_HMAC_SHA256
PKI_HMAC_SHA384
PKI_HMAC_SHA512
PKI_HMAC_MD5
```

#### Return Value

`Byte():` Key in byte array.

---

### <a id="VB_pbeKdf2Hex"></a>pbeKdf2Hex

Derives a hex-encoded key of any length from a password using the PBKDF2 algorithm from PKCS#5 v2.1. The salt and derived key are encoded in hexadecimal.

#### Syntax

[VBA]

```

Public Function pbeKdf2Hex ( _
    dkBytes As Long, _
    szPwd As String, _
    szSaltHex As String, _
    nCount As Long, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

dkBytes

:   Required length of key in bytes.

szPwd

:   Password (as normal text).

szSaltHex

:   Salt in hex-encoded format.

nCount

:   Iteration count.

nOptions

:   Hash algorithm to use in HMAC PRF. Select one from:

```

PKI_HMAC_SHA1
PKI_HMAC_SHA224
PKI_HMAC_SHA256
PKI_HMAC_SHA384
PKI_HMAC_SHA512
PKI_HMAC_MD5
```

#### Return Value

`String:` Key in hex format.

---

### <a id="VB_pbeScrypt"></a>pbeScrypt

Derives a key of any length from a password using the SCRYPT algorithm from RFC7914.

#### Syntax

[VBA]

```

Public Function pbeScrypt ( _
    dkBytes As Long, _
    lpPwd() As Byte, _
    lpSalt() As Byte, _
    nParamN As Long, _
    nParamR As Long, _
    nParamP As Long, _
    Optional nOptions As Long = 0 _
) As Byte()

```

#### Parameters

dkBytes

:   Required length of key in bytes.

lpPwd

:   Password encoded as byte array.

lpSalt

:   Salt in a byte array.

nParamN

:   CPU/Memory cost parameter `N` (`"costParameter"`), a number greater than one and a power of 2.

nParamR

:   Block size `r` (`"blockSize"`).

nParamP

:   Parallelization parameter `p` (`"parallelizationParameter"`).

nOptions

:   For future use.

#### Return Value

`Byte():` Key in byte array.

---

### <a id="VB_pbeScryptHex"></a>pbeScryptHex

Derives a hex-encoded key of any length from a password using the SCRYPT algorithm from RFC7914. The salt and derived key are encoded in hexadecimal.

#### Syntax

[VBA]

```

Public Function pbeScryptHex ( _
    dkBytes As Long, _
    szPwd As String, _
    szSaltHex As String, _
    nParamN As Long, _
    nParamR As Long, _
    nParamP As Long, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

dkBytes

:   Required length of key in bytes.

szPwd

:   Password (as normal text).

szSaltHex

:   Salt in hex-encoded format.

nParamN

:   CPU/Memory cost parameter `N` (`"costParameter"`), a number greater than one and a power of 2.

nParamR

:   Block size `r` (`"blockSize"`).

nParamP

:   Parallelization parameter `p` (`"parallelizationParameter"`).

nOptions

:   For future use.

#### Return Value

`String:` Key in hex format.

#### Example

```

Debug.Print pbeScryptHex(64, "password", "4E61436C", 1024, 8, 16)
' FDBABE1C9D3472007856E7190D01E9FE7C6AD7CBC8237830E77376634B3731622EAF30D92E22A3886FF109279D9830DAC727AFB94A83EE6D8360CBDFA2CC0640
```

---

### <a id="VB_pfxMakeFile"></a>pfxMakeFile

Create a PFX (PKCS-12) file from an X.509 certificate and (optional) encrypted private key file.

#### Syntax

[VBA]

```

Public Function pfxMakeFile ( _
    szFileOut As String, _
    szCertList As String, _
    Optional szKeyFile As String = "", _
    Optional szPassword As String = "", _
    Optional szFriendlyName As String = "", _
    Optional nOptions As Long = 0 _
) As Long

```

#### Parameters

szFileOut

:   Name of output file to be created.

szCertList

:   filename of the subject's X.509 certificate (or a string containing the certificate in base64 representation)
followed by optional extra certificates to be included separated by a semicolon (;).

szKeyFile

:   Filename of the subject's encrypted private key in pkcs-8 format (optional).

szPassword

:   Password for private key file and new PFX file.

szFriendlyName

:   Friendly name identification for the subject (optional).

nOptions

:   Specialist options

```

PKI_PFX_CLONE_KEY
PKI_PFX_PLAIN_CERT
PKI_PFX_STRONG_CERT
PKI_PFX_AES256_SHA256
PKI_PFX_DOUBLE_ENCRYPT
PKI_KEY_FORMAT_PEM
PKI_PFX_ALT_FORMAT
```

#### Return Value

`Long:` Zero on success else a nonzero error code

---

### <a id="VB_pkiCompileTime"></a>pkiCompileTime

Get date and time the CryptoSys PKI DLL module was last compiled.

#### Syntax

[VBA]

```

Public Function pkiCompileTime() As String

```

#### Return Value

`String:` Date and time string.

---

### <a id="VB_pkiErrorCode"></a>pkiErrorCode

Returns the error code of the error that occurred when calling the last function.

#### Syntax

[VBA]

```

Public Function pkiErrorCode() As Long

```

#### Return Value

`Long:` Error code (see [pkiErrorLookup](#VB_pkiErrorLookup)).

#### Remarks

Not all functions set this value.

---

### <a id="VB_pkiErrorLookup"></a>pkiErrorLookup

Get error message associated with a given error code.

#### Syntax

[VBA]

```

Public Function pkiErrorLookup ( _
    nErrCode As Long _
) As String

```

#### Parameters

nErrCode

:   Error code for which the message is required.

#### Return Value

`String:` Error message, or empty string if no corresponding error code.

---

### <a id="VB_pkiLastError"></a>pkiLastError

Get last error message set by previous function.

#### Syntax

[VBA]

```

Public Function pkiLastError() As String

```

#### Return Value

`String:` Final error message from last call (may be empty).

---

### <a id="VB_pkiLicenceType"></a>pkiLicenceType

Returns the ASCII value of the licence type.

#### Syntax

[VBA]

```

Public Function pkiLicenceType ( _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

nOptions

:   For future use.

#### Return Value

`String:` `D`=Developer `T`=Trial.

---

### <a id="VB_pkiModuleInfo"></a>pkiModuleInfo

Get additional information about the core DLL module.

#### Syntax

[VBA]

```

Public Function pkiModuleInfo ( _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

nOptions

:   For future use.

#### Return Value

`String:` Additional information, e.g. "Licensed Developer Edition".

---

### <a id="VB_pkiModuleName"></a>pkiModuleName

Get path name of the current process's module.

#### Syntax

[VBA]

```

Public Function pkiModuleName ( _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

nOptions

:   For future use.

#### Return Value

`String:` File path to current DLL module.

#### Example

```

Debug.Print pkiModuleName()
C:\WINDOWS\SYSTEM32\diCrPKI.dll
```

---

### <a id="VB_pkiPlatform"></a>pkiPlatform

Get platform the core DLL was compiled for.

#### Syntax

[VBA]

```

Public Function pkiPlatform() As String

```

#### Return Value

`String:` `"Win32"` or `"X64"`.

---

### <a id="VB_pkiVersion"></a>pkiVersion

Get version number of native core DLL.

#### Syntax

[VBA]

```

Public Function pkiVersion() As Long

```

#### Return Value

`Long:` Version number as an integer in form `Major*100*100 + Minor*100 + Revision`. For example, version 6.1.2 would return `60102`.

---

### <a id="VB_prfBytes"></a>prfBytes

Generate output bytes using a pseudorandom function (PRF).

#### Syntax

[VBA]

```

Public Function prfBytes ( _
    nBytes As Long, _
    lpMessage() As Byte, _
    lpKey() As Byte, _
    nOptions As Long, _
    Optional szCustom As String = "" _
) As Byte()

```

#### Parameters

nBytes

:   Required number of output bytes.

lpMessage

:   Input message data.

lpKey

:   Key (expected 128 or 256 bits long).

nOptions

:   PRF function to be used. Select one from:

```

PKI_KMAC_128
PKI_KMAC_256
```

szCustom

:   Customization string (optional).

#### Return Value

`Byte():` Output data in byte array.

#### Remarks

The KMAC128 and KMAC256 PRF functions are described in NIST SP800-185 (*SHA-3 Derived Functions*),
and use SHAKE128 and SHAKE256, respectively.
Note different order of parameters from core function.

---

### <a id="VB_pwdPrompt"></a>pwdPrompt

Prompt for a password in a dialog box.

#### Syntax

[VBA]

```

Public Function pwdPrompt ( _
    Optional szCaption As String = "", _
    Optional szPrompt As String = "" _
) As String

```

#### Parameters

szCaption

:   Caption for the dialog box

szPrompt

:   Wording for prompt (optional, default="Enter Password:")

#### Return Value

`String:` String containing password or empty string `""` if user cancels.

---

### <a id="VB_rngBytes"></a>rngBytes

Generate random bytes.

#### Syntax

[VBA]

```

Public Function rngBytes ( _
    nBytes As Long _
) As Byte()

```

#### Parameters

nBytes

:   Required number of random bytes.

#### Return Value

`Byte():` Array of random bytes.

---

### <a id="VB_rngGuid"></a>rngGuid

Generate a random 36-character Global Unique IDentifier (GUID) string.

#### Syntax

[VBA]

```

Public Function rngGuid() As String

```

#### Return Value

`String:` String of the form "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" where "x" is a hexadecimal digit [0-9a-f].

#### Example

```

Debug.Print rngGuid()
ba849198-168e-4632-a865-2761c9c8dd37
```

---

### <a id="VB_rngInitialize"></a>rngInitialize

Initialize the RNG generator using a seed file.

#### Syntax

[VBA]

```

Public Function rngInitialize ( _
    szSeedFile As String _
) As Long

```

#### Parameters

szSeedFile

:   Full path name of seed file. If the seed file does not exist, it will be created.

#### Return Value

`Long:` Zero if successful.

---

### <a id="VB_rngInitializeEx"></a>rngInitializeEx

Query and initialize the RNG generator using Intel(R) DRNG, if available.

#### Syntax

[VBA]

```

Public Function rngInitializeEx ( _
    Optional nOptions As Long = 0 _
) As Long

```

#### Parameters

nOptions

:   Specify `PKI_RNG_NO_INTEL_DRNG` to explicitly turn off support.

#### Return Value

`Long:` Support status for Intel(R) DRNG. If available, then returns a positive value (1,2,3); else a negative error code.

---

### <a id="VB_rsaDecodeMsg"></a>rsaDecodeMsg

Decode an EME or EMSA encoded message block according to PKCS#1.

#### Syntax

[VBA]

```

Public Function rsaDecodeMsg ( _
    lpInput() As Byte, _
    nOptions As Long _
) As Byte()

```

#### Parameters

lpInput

:   Data to be decoded.

nOptions

:   Include one of the following:

```

PKI_EME_PKCSV1_5
PKI_EME_OAEP
PKI_EMSIG_PKCSV1_5
```

If you have selected `PKI_EMSIG_PKCSV1_5`, then you can add
`PKI_EMSIG_DIGINFO` to decode an 'Encoded Message for Signature' block and output the whole `DigestInfo` data instead of just the message digest.
  

If you have selected PKI_EME_OAEP, then add one of these options to match the hash function used for EME-OAEP encoding:

```

PKI_HASH_SHA1
PKI_HASH_SHA224
PKI_HASH_SHA256
PKI_HASH_SHA384
PKI_HASH_SHA512
```

and optionally add `PKI_MGF_MGF1SHA1` to force the MGF hash function to be SHA-1 (default = same as encoding hash function set above).
  

Alternatively, ignore all the above and use the specialist option `PKI_EMSIG_ISO9796` to use the ISO9796-1 encoding for a signature.

#### Return Value

`Byte():` Decoded message.

#### Remarks

EME = Encoding Method for Encryption, EMSA = Encoding Method for Signature with Appendix.

---

### <a id="VB_rsaDecrypt"></a>rsaDecrypt

Decrypt a message encrypted using an RSA encryption scheme.

#### Syntax

[VBA]

```

Public Function rsaDecrypt ( _
    lpInput() As Byte, _
    szPrivateKeyFile As String, _
    szPassword As String, _
    nOptions As Long, _
    Optional szParameters As String = "" _
) As Byte()

```

#### Parameters

lpInput

:   Data to be decrypted.

szPrivateKeyFile

:   Name of the private key file, or a string containing the key in PEM format, or a valid internal private key string.

szPassword

:   Password for encrypted private key, or `""` if password is not required.

nOptions

:   Select one of the following:

```

PKI_EME_PKCSV1_5 (0 default)
PKI_EME_OAEP
```

szParameters

:   For future use.

#### Return Value

`Byte():` Decrypted data or an empty array on error.

#### Remarks

Note different order of parameters from core function.

---

### <a id="VB_rsaEncodeMsg"></a>rsaEncodeMsg

Encode an EME or EMSA encoded message block according to PKCS#1.

#### Syntax

[VBA]

```

Public Function rsaEncodeMsg ( _
    nBlockLen As Long, _
    lpInput() As Byte, _
    nOptions As Long _
) As Byte()

```

#### Parameters

nBlockLen

:   Length of output block in bytes (required).

lpInput

:   Data to be encoded.

nOptions

:   Include one of the following:

```

PKI_EME_PKCSV1_5
PKI_EME_OAEP
PKI_EMSIG_PKCSV1_5
```

If you have selected `PKI_EMSIG_PKCSV1_5`, then add one of these options to set the hash function for the signature message digest:

```

PKI_HASH_SHA1
PKI_HASH_SHA224
PKI_HASH_SHA256
PKI_HASH_SHA384
PKI_HASH_SHA512
PKI_HASH_MD5
PKI_HASH_MD2
```

and optionally add
`PKI_EMSIG_DIGESTONLY` as a flag to pass the message digest only as input to-be-signed (default = pass entire message).
  

If you have selected PKI_EME_OAEP, then add one of these options to set the hash function used for EME-OAEP encoding:

```

PKI_HASH_SHA1
PKI_HASH_SHA224
PKI_HASH_SHA256
PKI_HASH_SHA384
PKI_HASH_SHA512
```

and optionally add `PKI_MGF_MGF1SHA1` to force the MGF hash function to be SHA-1 (default = same as encoding hash function set above).
  

Alternatively, ignore all the above and use the specialist option `PKI_EMSIG_ISO9796` to use the ISO9796-1 encoding for a signature.

#### Return Value

`Byte():` Encoded message block.

#### Remarks

EME = Encoding Method for Encryption, EMSA = Encoding Method for Signature with Appendix.

---

### <a id="VB_rsaEncrypt"></a>rsaEncrypt

Encrypt a short message using RSA encryption.

#### Syntax

[VBA]

```

Public Function rsaEncrypt ( _
    lpInput() As Byte, _
    szPublicKeyFile As String, _
    Optional nOptions As Long = 0, _
    Optional szParameters As String = "" _
) As Byte()

```

#### Parameters

lpInput

:   Data to be encrypted.

szPublicKeyFile

:   Name of the public key file or X.509 certificate,
or a string containing the key or certificate in PEM format, or a valid internal public key string.

nOptions

:   Select one of the following:

```

PKI_EME_PKCSV1_5 (0 default)
PKI_EME_OAEP
```

If you have selected `PKI_EME_OAEP`, then add one of these options to set the hash function for EME-OAEP encoding:

```

PKI_HASH_SHA1
PKI_HASH_SHA224
PKI_HASH_SHA256
PKI_HASH_SHA384
PKI_HASH_SHA512
```

and, optionally, add `PKI_MGF_MGF1SHA1` to force the MGF hash function to be SHA-1 (default = same as encoding hash function set above).

szParameters

:   For future use.

#### Return Value

`Byte():` Encrypted data or an empty array on error.

#### Remarks

Note different order of parameters from core function.

---

### <a id="VB_rsaFromXMLString"></a>rsaFromXMLString

Create an RSA key string in internal format from an XML string.

#### Syntax

[VBA]

```

Public Function rsaFromXMLString ( _
    szXmlString As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szXmlString

:   The RSA public or private key in XML format.

nOptions

:   Use default zero to include the private key, if present, or add one of:
  

`PKI_XML_EXCLPRIVATE` to exclude the private key even if present, or
  

`PKI_XML_REQPRIVATE` to require the private key to exist in the XML input or fail.

#### Return Value

`String:` Key string in internal format or empty string on error.

---

### <a id="VB_rsaKeyBits"></a>rsaKeyBits

Get number of significant bits in RSA key modulus.

#### Syntax

[VBA]

```

Public Function rsaKeyBits ( _
    szKeyString As String _
) As Long

```

#### Parameters

szKeyString

:   Public or private key in internal string format.

#### Return Value

`Long:` Number of significant bits in key.

---

### <a id="VB_rsaKeyBytes"></a>rsaKeyBytes

Get number of bytes (octets) in RSA key modulus.

#### Syntax

[VBA]

```

Public Function rsaKeyBytes ( _
    szKeyString As String _
) As Long

```

#### Parameters

szKeyString

:   Public or private key in internal string format.

#### Return Value

`Long:` Number of bytes in key.

---

### <a id="VB_rsaKeyValue"></a>rsaKeyValue

Extract a base64-encoded RSA key value from internal key string.

#### Syntax

[VBA]

```

Public Function rsaKeyValue ( _
    szKeyString As String, _
    szFieldName As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szKeyString

:   Public or private key in internal string format.

szFieldName

:   Name of field to be extracted: `"Modulus"` or `"Exponent"`.

nOptions

:   For future use.

#### Return Value

`String:` Value encoded in base64 or an empty string on error.

---

### <a id="VB_rsaMakeKeys"></a>rsaMakeKeys

Generate an RSA public/private key pair and save as two key files.

#### Syntax

[VBA]

```

Public Function rsaMakeKeys ( _
    szPubKeyFile As String, _
    szPriKeyFile As String, _
    szPassword As String, _
    nBits As Long, _
    Optional nExpFermat As Long = PKI_RSAEXP_EQ_65537, _
    Optional szParams As String = "", _
    Optional nOptions As Long = 0 _
) As Long

```

#### Parameters

szPubKeyFile

:   Output filename for public key.

szPriKeyFile

:   Output filename for (encrypted) private key.

szPassword

:   Password for encrypted private key (required).

nBits

:   Required key modulus size in bits (min 96).

nExpFermat

:   Exponent [default=65537=F4]

szParams

:   Optional parameters. A set of attribute name=value pairs separated by a semicolon ";" (see remarks).

nOptions

:   Use 0 for defaults.
  

A flag to indicate the password-based encryption scheme to be used to encrypt the private key file. Select from:

```

PKI_PBE_SHA_3DES (0) for "pbeWithSHAAnd3-KeyTripleDES-CBC" from PKCS12 (default)
PKI_PBE_PBKDF2_DESEDE3 for PBKDF2 using des-EDE3-CBC
PKI_PBE_PBKDF2_AES128 for PBKDF2 using aes128-CBC
PKI_PBE_PBKDF2_AES192 for PBKDF2 using aes192-CBC
PKI_PBE_PBKDF2_AES256 for PBKDF2 using aes256-CBC
```

plus optionally one of the following to output in textual PEM format [default format=DER binary]

```

PKI_KEY_FORMAT_PEM
PKI_KEY_FORMAT_SSL
```

and, optionally, add `PKI_KEYGEN_INDICATE` to indicate progress in a console window.

#### Return Value

`Long:` Zero on success.

#### Remarks

Valid name-value pair parameters for `szParams` are:  

**count**=*integer* : To set the iteration count used in the PBKDF2 method, e.g. `"count=5000;"` [default=2048].  

**prf**=*hmac-name* : To change the HMAC algorithm used in the PBKDF2 method, e.g. `"prf=hmacWithSHA256;"` [default=`hmacWithSHA1`].  

**rngseed**=*string* : To add some user-supplied entropy for the key generation process, e.g. `"rngseed=pqrrr1234xyz;"`.  

Valid values for *hmac-name* are `{hmacWithSHA1|hmacWithSHA224|hmacWithSHA256|hmacWithSHA384|hmacWithSHA512}`.

#### Example

```

' Create a 2048-bit RSA key pair using defaults
r = rsaMakeKeys("myrsa2048.pub", "myrsa2048.p8e", "password", 2048)
' Same but using stronger security and in PEM format
r = rsaMakeKeys("myrsa2048ex.pub", "myrsa2048ex.p8e", "password1", 2048,,"count=6000;prf=hmacWithSHA256", PKI_PBE_PBKDF2_AES128 Or PKI_KEY_FORMAT_PEM)
```

---

### <a id="VB_rsaPublicKeyFromPrivate"></a>rsaPublicKeyFromPrivate

Convert an internal RSA private key string into an internal public key string.

#### Syntax

[VBA]

```

Public Function rsaPublicKeyFromPrivate ( _
    szKeyString As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szKeyString

:   Private key in internal string format.

nOptions

:   For future use.

#### Return Value

`String:` String containing an internal representation of the public key, or an empty string on error.

---

### <a id="VB_rsaRawPrivate"></a>rsaRawPrivate

Carry out RSA transformation on raw data using private key.

#### Syntax

[VBA]

```

Public Function rsaRawPrivate ( _
    lpData() As Byte, _
    szPrivateKey As String, _
    Optional nOptions As Long = 0 _
) As Byte()

```

#### Parameters

lpData

:   Data to be transformed.

szPrivateKey

:   Private key in internal string format.

nOptions

:   For future use.

#### Return Value

`Byte():` Transformed data.

#### Remarks

The data **must** be same length as key modulus (use `RSA_KeyBytes()` to find this).

---

### <a id="VB_rsaRawPublic"></a>rsaRawPublic

Carry out RSA transformation on raw data using public key.

#### Syntax

[VBA]

```

Public Function rsaRawPublic ( _
    lpData() As Byte, _
    szPublicKey As String, _
    Optional nOptions As Long = 0 _
) As Byte()

```

#### Parameters

lpData

:   Data to be transformed.

szPublicKey

:   Public key in internal string format.

nOptions

:   For future use.

#### Return Value

`Byte():` Transformed data.

#### Remarks

The data **must** be same length as key modulus (use `RSA_KeyBytes()` to find this).

---

### <a id="VB_rsaReadAnyPrivateKey"></a>rsaReadAnyPrivateKey

Read private key from a file or string containing a key into an "internal" public key string.

#### Syntax

[VBA]

```

Public Function rsaReadAnyPrivateKey ( _
    szKeyFileOrString As String, _
    Optional szPassword As String = "", _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szKeyFileOrString

:   Name of file containing the key, or a string containing the key in PEM format or XML format.

szPassword

:   Password, if the key is encrypted, or `""` if not.

nOptions

:   For future use.

#### Return Value

`String:` String containing an internal representation of the private key, or an empty string on error.

#### Remarks

This function is the same as [rsaReadPrivateKey](#VB_rsaReadPrivateKey).

---

### <a id="VB_rsaReadAnyPublicKey"></a>rsaReadAnyPublicKey

Read public key from a file or string containing a key into an "internal" public key string.

#### Syntax

[VBA]

```

Public Function rsaReadAnyPublicKey ( _
    szKeyFileOrString As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szKeyFileOrString

:   Name of file containing the key, or a string containing the key in PEM format or XML format.

nOptions

:   For future use.

#### Return Value

`String:` String containing an internal representation of the public key, or an empty string on error.

#### Remarks

This function is the same as [rsaReadPublicKey](#VB_rsaReadPublicKey).

---

### <a id="VB_rsaReadPrivateKey"></a>rsaReadPrivateKey

Read private key from a file or string containing a key into an "internal" public key string.

#### Syntax

[VBA]

```

Public Function rsaReadPrivateKey ( _
    szKeyFileOrString As String, _
    Optional szPassword As String = "", _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szKeyFileOrString

:   Name of file containing the key, or a string containing the key in PEM format or XML format.

szPassword

:   Password, if the key is encrypted, or `""` if not.

nOptions

:   For future use.

#### Return Value

`String:` String containing an internal representation of the private key, or an empty string on error.

---

### <a id="VB_rsaReadPublicKey"></a>rsaReadPublicKey

Read public key from a file or string containing a key into an "internal" public key string.

#### Syntax

[VBA]

```

Public Function rsaReadPublicKey ( _
    szKeyFileOrString As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szKeyFileOrString

:   Name of file containing the key, or a string containing the key in PEM format or XML format.

nOptions

:   For future use.

#### Return Value

`String:` String containing an internal representation of the public key, or an empty string on error.

---

### <a id="VB_rsaSaveEncKey"></a>rsaSaveEncKey

Save an internal RSA key string to an encrypted key file.

#### Syntax

[VBA]

```

Public Function rsaSaveEncKey ( _
    szOutputFile As String, _
    szKeyStr As String, _
    szPassword As String, _
    Optional szParams As String = "", _
    Optional nOptions As Long = 0 _
) As Long

```

#### Parameters

szOutputFile

:   Name of output file to be created.

szKeyStr

:   The private RSA key as an internal key string.

szPassword

:   Password for encrypted private key (required).

szParams

:   Optional parameters. A set of attribute name=value pairs separated by a semicolon ";" (see remarks).

nOptions

:   Use 0 for defaults.
  

A flag to indicate the password-based encryption scheme to be used to encrypt the private key file. Select from:

```

PKI_PBE_SHA_3DES (0) for "pbeWithSHAAnd3-KeyTripleDES-CBC" from PKCS12 (default)
PKI_PBE_PBKDF2_DESEDE3 for PBKDF2 using des-EDE3-CBC
PKI_PBE_PBKDF2_AES128 for PBKDF2 using aes128-CBC
PKI_PBE_PBKDF2_AES192 for PBKDF2 using aes192-CBC
PKI_PBE_PBKDF2_AES256 for PBKDF2 using aes256-CBC
```

plus optionally one of the following to output in textual PEM format [default format=DER binary]

```

PKI_KEY_FORMAT_PEM
PKI_KEY_FORMAT_SSL
```

#### Return Value

`Long:` Zero on success else a nonzero error code.

#### Remarks

Valid name-value pair parameters for `szParams` are:  

**count**=*integer* : To set the iteration count used in the PBKDF2 method, e.g. `"count=5000;"` [default=2048].  

**prf**=*hmac-name* : To change the HMAC algorithm used in the PBKDF2 method, e.g. `"prf=hmacWithSHA256;"` [default=`hmacWithSHA1`].  

Valid values for *hmac-name* are `{hmacWithSHA1|hmacWithSHA224|hmacWithSHA256|hmacWithSHA384|hmacWithSHA512}`.

---

### <a id="VB_rsaSaveKey"></a>rsaSaveKey

Save an internal RSA key string to a key file.

#### Syntax

[VBA]

```

Public Function rsaSaveKey ( _
    szOutputFile As String, _
    szKeyStr As String, _
    Optional nOptions As Long = 0 _
) As Long

```

#### Parameters

szOutputFile

:   Name of output file to be created.

szKeyStr

:   Key string (public or private) in internal format.

nOptions

:   Add one of the following to output in textual PEM format [default (0) format=DER binary]

```

PKI_KEY_FORMAT_PEM
PKI_KEY_FORMAT_SSL
```

#### Return Value

`Long:` Zero on success else a nonzero error code.

#### Remarks

If the key is a private key it will be saved in *unencrypted* form.
To save a private key in encrypted form, use [rsaSaveEncKey](#VB_rsaSaveEncKey).

---

### <a id="VB_rsaToXMLString"></a>rsaToXMLString

Create an XML string representation of an RSA internal key string.

#### Syntax

[VBA]

```

Public Function rsaToXMLString ( _
    szKeyString As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szKeyString

:   The RSA public or private key in internal format.

nOptions

:   Default (0) to output in appropriate W3C standard format
(`RSAKeyValue` for public key and `RSAKeyPair` for private key), or select and combine:
  

`PKI_XML_RSAKEYVALUE` to force private key output as .NET-compatible `RSAKeyValue` format (instead of W3C `RSAKeyPair`)
  

`PKI_XML_EXCLPRIVATE` to exclude the private key (use to get a public key `RSAKeyValue` from a private key)
  

`PKI_XML_HEXBINARY` to output with data in non-conforming (but convenient) `hexBinary` format.

#### Return Value

`String:` XML string or empty string on error.

---

### <a id="VB_rsaToXMLStringEx"></a>rsaToXMLStringEx

Create an XML string representation of an RSA internal key string with option to add a namespace prefix.

#### Syntax

[VBA]

```

Public Function rsaToXMLStringEx ( _
    szKeyString As String, _
    szPrefix As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szKeyString

:   The RSA public or private key in internal format.

szPrefix

:   Namespace prefix to be added to all elements, e.g. `"ds"`.

nOptions

:   Default (0) to output in appropriate W3C standard format
(`RSAKeyValue` for public key and `RSAKeyPair` for private key), or select and combine:
  

`PKI_XML_RSAKEYVALUE` to force private key output as .NET-compatible `RSAKeyValue` format (instead of W3C `RSAKeyPair`)
  

`PKI_XML_EXCLPRIVATE` to exclude the private key (use to get a public key `RSAKeyValue` from a private key)
  

`PKI_XML_HEXBINARY` to output with data in non-conforming (but convenient) `hexBinary` format.

#### Return Value

`String:` XML string or empty string on error.

#### Remarks

Use this extended function to add a namespace prefix to all elements in the XML output; for example, `<ds:RSAKeyValue>`.

---

### <a id="VB_sigSignData"></a>sigSignData

Compute a signature value over data in a byte array.

#### Syntax

[VBA]

```

Public Function sigSignData ( _
    lpData() As Byte, _
    szKeyFile As String, _
    szPassword As String, _
    szAlgName As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

lpData

:   Data to be signed.

szKeyFile

:   name of the private key file or a string containing the key in PEM format, or a valid internal private key string.

szPassword

:   Password for the private key, or `""` if not required.

szAlgName

:   Signature algorithm to be used:

```

"sha1WithRSAEncryption"
"sha224WithRSAEncryption"
"sha256WithRSAEncryption"
"sha384WithRSAEncryption"
"sha512WithRSAEncryption"
"md5WithRSAEncryption"
"ecdsaWithSHA1"
"ecdsaWithSHA224"
"ecdsaWithSHA256"
"ecdsaWithSHA384"
"ecdsaWithSHA512"
"RSA-PSS-SHA1"
"RSA-PSS-SHA224"
"RSA-PSS-SHA256"
"RSA-PSS-SHA384"
"RSA-PSS-SHA512"
"Ed25519"
```

nOptions

:   Use 0 for defaults.
  

Add the bitflag `PKI_SIG_USEDIGEST` to pass the digest value of the data-to-be-signed as the `lpData` argument.
  

To change the format of the output (default base64 encoded), add one of:

```

PKI_ENCODE_BASE64URL
PKI_ENCODE_HEX
```

Options for ECDSA signatures only:

```

PKI_SIG_DETERMINISTIC
PKI_SIG_ASN1DER
```

Options for RSA-PSS signatures only to set the salt length (default = `hLen`):

```

PKI_PSS_SALTLEN_HLEN
PKI_PSS_SALTLEN_MAX
PKI_PSS_SALTLEN_20
PKI_PSS_SALTLEN_ZERO
```

and, optionally, add `PKI_MGF_MGF1SHA1` (RSA-PSS only) to force the MGF hash function to be SHA-1 (default = same as signature hash algorithm).

#### Return Value

`String:` The signature encoded in base64, or an empty string on error.

---

### <a id="VB_sigSignFile"></a>sigSignFile

Compute a signature value over data in a file.

#### Syntax

[VBA]

```

Public Function sigSignFile ( _
    szDataFile As String, _
    szKeyFile As String, _
    szPassword As String, _
    szAlgName As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szDataFile

:   Name of file to be signed.

szKeyFile

:   name of the private key file or a string containing the key in PEM format, or a valid internal private key string.

szPassword

:   Password for the private key, or `""` if not required.

szAlgName

:   Signature algorithm to be used:

```

"sha1WithRSAEncryption"
"sha224WithRSAEncryption"
"sha256WithRSAEncryption"
"sha384WithRSAEncryption"
"sha512WithRSAEncryption"
"md5WithRSAEncryption"
"ecdsaWithSHA1"
"ecdsaWithSHA224"
"ecdsaWithSHA256"
"ecdsaWithSHA384"
"ecdsaWithSHA512"
"RSA-PSS-SHA1"
"RSA-PSS-SHA224"
"RSA-PSS-SHA256"
"RSA-PSS-SHA384"
"RSA-PSS-SHA512"
```

nOptions

:   Use 0 for defaults.
  

To change the format of the output (default base64 encoded), add one of:

```

PKI_ENCODE_BASE64URL
PKI_ENCODE_HEX
```

Options for ECDSA signatures only:

```

PKI_SIG_DETERMINISTIC
PKI_SIG_ASN1DER
```

Options for RSA-PSS signatures only to set the salt length (default = `hLen`):

```

PKI_PSS_SALTLEN_HLEN
PKI_PSS_SALTLEN_MAX
PKI_PSS_SALTLEN_20
PKI_PSS_SALTLEN_ZERO
```

and, optionally, add `PKI_MGF_MGF1SHA1` (RSA-PSS only) to force the MGF hash function to be SHA-1 (default = same as signature hash algorithm).

#### Return Value

`String:` The signature encoded in base64, or an empty string on error.

#### Remarks

Ed25519 is not available with this function. To sign using Ed25519, read in the file to a byte array and use [sigSignData](#VB_sigSignData).

---

### <a id="VB_sigVerifyData"></a>sigVerifyData

Verify a signature value over data in a byte array.

#### Syntax

[VBA]

```

Public Function sigVerifyData ( _
    szSignature As String, _
    lpData() As Byte, _
    szCertOrKey As String, _
    szAlgName As String, _
    Optional nOptions As Long = 0 _
) As Long

```

#### Parameters

szSignature

:   Encoded signature value

lpData

:   Data to be verified.

szCertOrKey

:   Name of X.509 certificate or public key file, or a string containing the certificate in base64 representation,
or the public key in PEM format, or a valid internal public key string.

szAlgName

:   Signature algorithm to be used:

```

"sha1WithRSAEncryption"
"sha224WithRSAEncryption"
"sha256WithRSAEncryption"
"sha384WithRSAEncryption"
"sha512WithRSAEncryption"
"md5WithRSAEncryption"
"ecdsaWithSHA1"
"ecdsaWithSHA224"
"ecdsaWithSHA256"
"ecdsaWithSHA384"
"ecdsaWithSHA512"
"RSA-PSS-SHA1"
"RSA-PSS-SHA224"
"RSA-PSS-SHA256"
"RSA-PSS-SHA384"
"RSA-PSS-SHA512"
"Ed25519"
```

nOptions

:   Use 0 for defaults.
Add the bitflag `PKI_SIG_USEDIGEST` to pass the digest value of the data-to-be-signed as the `lpData` argument instead of the data itself.
Add `PKI_MGF_MGF1SHA1` (RSA-PSS only) to force the MGF hash function to be SHA-1 (default = same as signature hash algorithm).

#### Return Value

`Long:` Zero (0) if the signature is valid; otherwise a nonzero error code.

---

### <a id="VB_smimeQuery"></a>smimeQuery

Query an S/MIME entity for selected information.

#### Syntax

[VBA]

```

Public Function smimeQuery ( _
    szFileIn As String, _
    szQuery As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szFileIn

:   Name of input file.

szQuery

:   Query string (case insensitive). Valid queries are:

```

"content-type"
"smime-type"
"encoding"
"name"
"filename"
```

nOptions

:   For future use.

#### Return Value

`String:` String containing the result or an empty string if not found or error.

#### Example

```

Debug.Print smimeQuery("cmsalice2bob-smime-env.txt", "smime-type")
enveloped-data
```

---

### <a id="VB_wipeBytes"></a>wipeBytes

Wipe a byte array securely.

#### Syntax

[VBA]

```

Public Function wipeBytes ( _
    ByRef lpToWipe() As Byte _
) As Byte()

```

#### Parameters

lpToWipe

:   Byte array to be wiped.

#### Return Value

`Byte():` An empty byte array.

#### Example

```

Dim lpData() As Byte
lpData = cnvFromHex("DEADBEEF")
Debug.Print "BEFORE: 0x(" & cnvToHex(lpData) & ")" ' BEFORE: 0x(DEADBEEF)
Call wipeBytes(lpData)
Debug.Print "AFTER: 0x(" & cnvToHex(lpData) & ")" ' AFTER: 0x()
```

---

### <a id="VB_wipeString"></a>wipeString

Wipe a string securely and return an empty string.

#### Syntax

[VBA]

```

Public Function wipeString ( _
    ByRef szToWipe As String _
) As String

```

#### Parameters

szToWipe

:   String to be wiped.

#### Return Value

`String:` An empty string.

#### Remarks

To use: `szToWipe = wipeString(szToWipe)`

#### Example

```

Dim strData As String
strData = "my deepest secrets"
strData = wipeString(strData)
```

---

### <a id="VB_x509CertThumb"></a>x509CertThumb

Calculate the thumbprint (message digest value) of an X.509 certificate.

#### Syntax

[VBA]

```

Public Function x509CertThumb ( _
    szCertFile As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szCertFile

:   Name of input file.

nOptions

:   Algorithm to be used. Select one from:

```

PKI_HASH_SHA1 (0 = default)
PKI_HASH_SHA224
PKI_HASH_SHA256
PKI_HASH_SHA384
PKI_HASH_SHA512
PKI_HASH_MD5
```

#### Return Value

`String:` Message digest in hex format or empty string on error.

---

### <a id="VB_x509HashIssuerAndSN"></a>x509HashIssuerAndSN

Calculate the message digest hash of the PKCS #7 issuerAndSerialNumber value of an X.509 certificate.

#### Syntax

[VBA]

```

Public Function x509HashIssuerAndSN ( _
    szCertFile As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szCertFile

:   Name of input file.

nOptions

:   Algorithm to be used. Select one from:

```

PKI_HASH_SHA1 (0 = default)
PKI_HASH_SHA224
PKI_HASH_SHA256
PKI_HASH_SHA384
PKI_HASH_SHA512
PKI_HASH_MD5
```

#### Return Value

`String:` Message digest in hex format or empty string on error.

---

### <a id="VB_x509QueryCert"></a>x509QueryCert

Query an X.509 certificate file for selected information.

#### Syntax

[VBA]

```

Public Function x509QueryCert ( _
    szCertFile As String, _
    szQuery As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szCertFile

:   Name of X.509 certificate file (or base64 representation).

szQuery

:   Query string (case insensitive). Valid queries are:

```

"version"
"serialNumber"
"signatureAlgorithm"
"sigAlgId"
"signatureValue"
"notBefore"
"notAfter"
"issuerName"
"subjectName"
"subjectPublicKeyAlgorithm"
"subjectKeyIdentifier"
"authorityKeyIdentifier"
"rfc822Name"
"isCA"
"keyUsageString"
"extKeyUsageString"
"cRLDistributionPointsURI"
"authorityInfoAccessURI"
"subjectAltName"
"hashAlgorithm"
"pssParams"
```

nOptions

:   Use 0 for default or add any of:

```

PKI_X509_LATIN1 or PKI_X509_UTF8
PKI_X509_LDAP
PKI_X509_DECIMAL
```

#### Return Value

`String:` String containing the result or an empty string if not found or error.

#### Remarks

`PKI_X509_UTF8` will output attribute string encoded in UTF-8.
`PKI_X509_LATIN1` will *attempt* to convert output to Latin-1 encoding.

#### Example

```

Debug.Print x509QueryCert("AliceRSASignByCarl.cer", "subjectName")
CN=AliceRSA
```

---

### <a id="VB_x509ReadCertStringFromP7Chain"></a>x509ReadCertStringFromP7Chain

Read an X.509 certificate into a base64-encoded string from PKCS-7 "certs-only" data.

#### Syntax

[VBA]

```

Public Function x509ReadCertStringFromP7Chain ( _
    szP7cFile As String, _
    nIndex As Long, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szP7cFile

:   Filename of a PKCS-7 "certs-only" file, or a string containing its PEM textual representation.

nIndex

:   Index of certificate (1,2,...) in the chain to extract.

nOptions

:   For future use.

#### Return Value

`String:` String in continuous base64 format, or an empty string on error or if not found.

#### Remarks

Use `X509_GetCertCountInP7Chain()` to find number of certificates in the chain.

---

### <a id="VB_x509ReadCertStringFromPFX"></a>x509ReadCertStringFromPFX

Read an X.509 certificate into a base64-encoded string from PKCS-12 PFX/.p12 data.

#### Syntax

[VBA]

```

Public Function x509ReadCertStringFromPFX ( _
    szPfxFile As String, _
    szPassword As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szPfxFile

:   Filename of a PFX file, or a string containing its PEM textual representation.

szPassword

:   Password or `""` if certificate is not encrypted.

nOptions

:   For future use.

#### Return Value

`String:` String in continuous base64 format, or an empty string on error.

---

### <a id="VB_x509ReadStringFromFile"></a>x509ReadStringFromFile

Read an X.509 certificate into a base64-encoded string.

#### Syntax

[VBA]

```

Public Function x509ReadStringFromFile ( _
    szCertFile As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szCertFile

:   Name of X.509 certificate file.

nOptions

:   For future use.

#### Return Value

`String:` String in continuous base64 format, or an empty string on error.

---

### <a id="VB_x509TextDumpToString"></a>x509TextDumpToString

Dump details of an X.509 certificate or a X.509 certificate revocation list (CRL) or a PKCS-10 certificate signing request (CSR) to a string.

#### Syntax

[VBA]

```

Public Function x509TextDumpToString ( _
    szCertFile As String, _
    Optional nOptions As Long = 0 _
) As String

```

#### Parameters

szCertFile

:   Name of input file (or its base64 or PEM string representation).

nOptions

:   Use 0 for default or add any of:

```

PKI_X509_LATIN1
PKI_X509_LDAP
PKI_X509_DECIMAL
```

#### Return Value

`String:` String containing the result, or an empty string on error.

---

### <a id="VB_xofBytes"></a>xofBytes

Generate bytes using an eXtendable-Output Function (XOF).

#### Syntax

[VBA]

```

Public Function xofBytes ( _
    nBytes As Long, _
    lpMessage() As Byte, _
    nOptions As Long _
) As Byte()

```

#### Parameters

nBytes

:   Required number of output bytes.

lpMessage

:   Input message data.

nOptions

:   XOF algorithm to be used. Select one from:

```

PKI_XOF_SHAKE128
PKI_XOF_SHAKE256
PKI_XOF_MGF1_SHA1
PKI_XOF_MGF1_SHA256
PKI_XOF_MGF1_SHA512
```

#### Return Value

`Byte():` Output data in byte array.

#### Remarks

The SHAKE128 and SHAKE256 XOF functions are described in NIST.FIPS.202.
MGF1 is described in PKCS#1/RFC2437.

---

[[Contents](#topofpage)] [[Index](#index)]

<a id="cppfunctions"></a>C++ (STL) Functions
--------------------------------------------

See [Using with C++ (STL)](#UsingWithCpp).

* <a id="dipki::Asn1::TextDump"></a>[dipki::Asn1::TextDump](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_asn1.html#afada981d58be3f2c270f7729f345818e "External link") - Dump details of an ASN.1 formatted data file to a text file.
* <a id="dipki::Asn1::TextDumpToString"></a>[dipki::Asn1::TextDumpToString](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_asn1.html#a8a9c6f7105357424caaecac677ec056b "External link") - Dump details of ASN.1 formatted data to a string.
* <a id="dipki::Asn1::Type"></a>[dipki::Asn1::Type](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_asn1.html#abe66fd14daf02c34fa6221b8ff39c230 "External link") - Describe the type of ASN.1 data.
* <a id="dipki::Cipher::AlgName"></a>[dipki::Cipher::AlgName](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#acd81730fa40163344d3742bd047af93e "External link") - Get the algorithm name.
* <a id="dipki::Cipher::BlockBytes"></a>[dipki::Cipher::BlockBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#a808966d8af3ce2610cd2d66c8049993e "External link") - Get the block size in bytes for a given cipher algorithm.
* <a id="dipki::Cipher::Decrypt_1"></a>[dipki::Cipher::Decrypt](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#aefaac2005f99930eda0875a4e97c7a49 "External link") [1/2]  - Decrypt data in a byte array using the specified block cipher algorithm, mode and padding.
* <a id="dipki::Cipher::Decrypt_2"></a>[dipki::Cipher::Decrypt](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#a11632dee81df1824241acb90ea1b73e8 "External link") [2/2]  - Decrypt data in a byte array using the specified block cipher algorithm, mode and padding.
* <a id="dipki::Cipher::DecryptAEAD"></a>[dipki::Cipher::DecryptAEAD](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#a5c29247a4f848796ab7f832391eaa781 "External link") - Decrypt data using authenticated encryption with additional authenticated data (AAD).
* <a id="dipki::Cipher::DecryptBlock"></a>[dipki::Cipher::DecryptBlock](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#a6dd9c85f629106352b62196b30c69f50 "External link") - Decrypt a block of data.
* <a id="dipki::Cipher::Encrypt_1"></a>[dipki::Cipher::Encrypt](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#a1b78e8753a8eee4d335cc830b2337edd "External link") [1/2]  - Encrypt data in a byte array using the specified block cipher algorithm, mode and padding.
* <a id="dipki::Cipher::Encrypt_2"></a>[dipki::Cipher::Encrypt](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#ae84957081fede5e2934fb68d1d60b9ba "External link") [2/2]  - Encrypt data in a byte array using the specified block cipher algorithm, mode and padding.
* <a id="dipki::Cipher::EncryptAEAD"></a>[dipki::Cipher::EncryptAEAD](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#abb21e6a14b2bcd15317f952eca4ab581 "External link") - Encrypt data using authenticated encryption with additional authenticated data (AAD).
* <a id="dipki::Cipher::EncryptBlock"></a>[dipki::Cipher::EncryptBlock](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#ae4a6e9b510be24d2536c8f2a1b1bd03b "External link") - Encrypt a block of data.
* <a id="dipki::Cipher::FileDecrypt"></a>[dipki::Cipher::FileDecrypt](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#ac4575aa726b28151e63bc39523aba95a "External link") - Decrypt a file.
* <a id="dipki::Cipher::FileEncrypt"></a>[dipki::Cipher::FileEncrypt](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#ae15ee22f917aca4fae21ee1c8ab2a8fd "External link") - Encrypt a file.
* <a id="dipki::Cipher::KeyBytes"></a>[dipki::Cipher::KeyBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#a02f53d053a940ceb3eb092bea5daf061 "External link") - Get the key size in bytes for a given cipher algorithm.
* <a id="dipki::Cipher::KeyUnwrap"></a>[dipki::Cipher::KeyUnwrap](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#af55e7ae91b01993b1a6c02cc86c51a68 "External link") - Unwrap (decrypt) key material with a key-encryption key.
* <a id="dipki::Cipher::KeyWrap"></a>[dipki::Cipher::KeyWrap](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#a9aebd1dab4c63244371c589d5ef5c9ba "External link") - Wrap (encrypt) key material with a key-encryption key.
* <a id="dipki::Cipher::Pad"></a>[dipki::Cipher::Pad](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#a9c5ae708169fffeb46129fa955faf200 "External link") - Pad byte array to correct length for ECB and CBC encryption.
* <a id="dipki::Cipher::Unpad"></a>[dipki::Cipher::Unpad](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cipher.html#a6c37c6b4d8a88785a393e019f2eab19d "External link") - Remove padding from an encryption block.
* <a id="dipki::Cms::GetSigDataDigest"></a>[dipki::Cms::GetSigDataDigest](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a6ae8fc70eebf1dbc348b7df0c1273bc6 "External link") - Extract the message digest from a signed-data CMS object file.
* <a id="dipki::Cms::MakeComprData"></a>[dipki::Cms::MakeComprData](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a872169f6f2c0e75785c6021a23cfce63 "External link") - Create a CMS compressed-data file (.p7z) from an existing input file [binary file --> binary file].
* <a id="dipki::Cms::MakeDetachedSig"></a>[dipki::Cms::MakeDetachedSig](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a038c7a5e87adab4472215ace4b425312 "External link") - Create a "detached signature" CMS signed-data object from a message digest of the content [hexdigest --> file].
* <a id="dipki::Cms::MakeEnvData_1"></a>[dipki::Cms::MakeEnvData](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a79d88f02853eff963ad194bf98d4bcd8 "External link") [1/2]  - Create a CMS enveloped-data object for one or more recipients [file --> file].
* <a id="dipki::Cms::MakeEnvData_2"></a>[dipki::Cms::MakeEnvData](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#acf05de0c16ab1d1b7a0ed588f06fc20b "External link") [2/2]  - Create a CMS enveloped-data object using pwri or kekri scheme [file --> file].
* <a id="dipki::Cms::MakeEnvDataFromBytes"></a>[dipki::Cms::MakeEnvDataFromBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a8d245dbe1764362c0439b710e9dd344b "External link") - Create a CMS enveloped-data object for one or more recipients [bytes --> file].
* <a id="dipki::Cms::MakeEnvDataFromString"></a>[dipki::Cms::MakeEnvDataFromString](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a96b9276b195b0a13bde9fb2a0ecee69d "External link") - Create a CMS enveloped-data object for one or more recipients [string --> file].
* <a id="dipki::Cms::MakeSigData"></a>[dipki::Cms::MakeSigData](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#af25430f2abccb6b40baa9e597f619369 "External link") - Create a CMS signed-data object from a data file [file --> file].
* <a id="dipki::Cms::MakeSigDataFromBytes"></a>[dipki::Cms::MakeSigDataFromBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#aafc0c8beaa5bb8e19d7242c9c6f79487 "External link") - Create a CMS signed-data object from data [bytes --> file].
* <a id="dipki::Cms::MakeSigDataFromPseudo"></a>[dipki::Cms::MakeSigDataFromPseudo](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a49dcc699222cf90dca0e47eb6e706ed5 "External link") - Create a SignedData object from a "pseudo" object.
* <a id="dipki::Cms::MakeSigDataFromSigValue"></a>[dipki::Cms::MakeSigDataFromSigValue](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a5bb3e903055c1877483f9d4e912808a2 "External link") - Create a CMS object of type SignedData using a pre-computed signature value [bytes --> file].
* <a id="dipki::Cms::MakeSigDataFromString"></a>[dipki::Cms::MakeSigDataFromString](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a013c817c056f71eb9e12eab5991a814d "External link") - Create a CMS signed-data object from a string [string --> file].
* <a id="dipki::Cms::QueryEnvData"></a>[dipki::Cms::QueryEnvData](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a8f8afaad52471d4c8d9998e20081da33 "External link") - Query a CMS enveloped-data object for selected information.
* <a id="dipki::Cms::QuerySigData"></a>[dipki::Cms::QuerySigData](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#ae57ff9120187189f447b47fce29aa05c "External link") - Query a CMS signed-data object for selected information.
* <a id="dipki::Cms::ReadComprData"></a>[dipki::Cms::ReadComprData](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#af369d8fd68584480f57befcd10117261 "External link") - Read and extract the decompressed contents of a CMS compressed-data file [binary file --> binary file].
* <a id="dipki::Cms::ReadEnvDataToBytes"></a>[dipki::Cms::ReadEnvDataToBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#adf858b4035b5091bbd9cdf6161f364f3 "External link") - Read and decrypt a CMS enveloped-data object to a byte array [file --> bytes].
* <a id="dipki::Cms::ReadEnvDataToFile"></a>[dipki::Cms::ReadEnvDataToFile](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#afad6be6e9ab0199d8a8a4143f731f6f6 "External link") - Read and decrypt a CMS enveloped-data object to a file [file --> file].
* <a id="dipki::Cms::ReadSigDataToBytes"></a>[dipki::Cms::ReadSigDataToBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a195dd3ffebf14da82afbcb38c0d3ee70 "External link") - Read and decrypt a CMS enveloped-data object to a byte array [file --> bytes].
* <a id="dipki::Cms::ReadSigDataToFile"></a>[dipki::Cms::ReadSigDataToFile](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a7bd1e326ed04aac001b35514bc1e1a89 "External link") - Read the content from a CMS signed-data object file [file --> file].
* <a id="dipki::Cms::VerifySigData"></a>[dipki::Cms::VerifySigData](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cms.html#a716d8daac452731ba32ebf01616f02d9 "External link") - Verify the signature and content of a signed-data CMS object file.
* <a id="dipki::Cnv::CheckUTF8"></a>[dipki::Cnv::CheckUTF8](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a03053e41be4471efaacc4c178671e92d "External link") - Check that a byte array contains only valid UTF-8 encoded characters.
* <a id="dipki::Cnv::CheckUTF8CodeAsString"></a>[dipki::Cnv::CheckUTF8CodeAsString](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#aee5aa359ca1c5aa048828f3ac0782421 "External link") - Return a string describing an integer code returned by Cnv::CheckUTF8 or Cnv::CheckUTF8File.
* <a id="dipki::Cnv::CheckUTF8File"></a>[dipki::Cnv::CheckUTF8File](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#acdd517ccb3e1c1c367e2425c1571420a "External link") - Check that a file contains only valid UTF-8 encoded characters.
* <a id="dipki::Cnv::FromBase58"></a>[dipki::Cnv::FromBase58](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a1eb3f31614c1aa5286af0c7823f7f8db "External link") - Decodes a base58-encoded string as an array of bytes.
* <a id="dipki::Cnv::FromBase64"></a>[dipki::Cnv::FromBase64](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#af74aa67af858aea47407c4e55fd23e97 "External link") - Decodes a base64-encoded string as an array of bytes.
* <a id="dipki::Cnv::FromHex"></a>[dipki::Cnv::FromHex](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#ae5758db60d6e736aa7f02d9897d88d25 "External link") - Decodes a hexadecimal-encoded string as an array of bytes.
* <a id="dipki::Cnv::Latin1FromUTF8Bytes"></a>[dipki::Cnv::Latin1FromUTF8Bytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a53aff21e51cfd1b4b496d61d1cf8959a "External link") - Converts UTF-8 encoded array of bytes into a Latin-1 string, if possible.
* <a id="dipki::Cnv::NumFromBytes"></a>[dipki::Cnv::NumFromBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a258627606677910096c29c970efb3110 "External link") - Convert the leftmost four bytes of an array to an unsigned 32-bit integer.
* <a id="dipki::Cnv::NumToBytes"></a>[dipki::Cnv::NumToBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a981d66f0e73e13f80707c841fe62c3a2 "External link") - Convert a 32-bit integer to an array of 4 bytes.
* <a id="dipki::Cnv::ReverseBytes"></a>[dipki::Cnv::ReverseBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a6ae41201c7f200770c2f1d3c4516fb67 "External link") - Reverse the order of a byte array.
* <a id="dipki::Cnv::ShortPathName"></a>[dipki::Cnv::ShortPathName](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a8d38d8d0febbd2e163e07766ce50921a "External link") - Retrieve the Windows short path form of the specified path.
* <a id="dipki::Cnv::ToBase58"></a>[dipki::Cnv::ToBase58](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#af09afd9cc0eacd54cbc66b9ea0ff1c43 "External link") - Encodes an array of bytes as a base58-encoded string.
* <a id="dipki::Cnv::ToBase64_1"></a>[dipki::Cnv::ToBase64](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a53fa6ab77bbb5623e134f72199a407d6 "External link") [1/2]  - Encodes an array of bytes as a base64-encoded string.
* <a id="dipki::Cnv::ToBase64_2"></a>[dipki::Cnv::ToBase64](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a8e32a430afe218683b5f63f64b08e641 "External link") [2/2]  - Encodes a string as a base64-encoded string.
* <a id="dipki::Cnv::ToHex_1"></a>[dipki::Cnv::ToHex](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a5810eaae94a26966d7b0f3f38d020b53 "External link") [1/2]  - Encodes an array of bytes as a hexadecimal-encoded string.
* <a id="dipki::Cnv::ToHex_2"></a>[dipki::Cnv::ToHex](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#ab8105e17761c59fbd94dada6e4ad553b "External link") [2/2]  - Encodes a string as a hexadecimal-encoded string.
* <a id="dipki::Cnv::UTF8BytesFromLatin1"></a>[dipki::Cnv::UTF8BytesFromLatin1](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#ab68bc113efd373567ab51914ee0f88d3 "External link") - Converts a string of 8-bit Latin-1 characters into a UTF-8 encoded array of bytes.
* <a id="dipki::Cnv::Utf8FromWide"></a>[dipki::Cnv::Utf8FromWide](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_cnv.html#a9ede836655f91e2caa3288720d6c08fa "External link") - Map a UTF-16 (wide character) string to a UTF-8-encoded string.
* <a id="dipki::Compr::Compress"></a>[dipki::Compr::Compress](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_compr.html#adb335ad3ad155607aae0211338a9b699 "External link") - Compress data using zlib compression.
* <a id="dipki::Compr::Uncompress"></a>[dipki::Compr::Uncompress](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_compr.html#a24cae59498eff5ebf00d075cb1dc7b02 "External link") - Uncompress data using zlib compression.
* <a id="dipki::Ecc::CurveNameAsString"></a>[dipki::Ecc::CurveNameAsString](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#addd566d05538f74acb0dba09786f8632 "External link") - Get curve name as a string.
* <a id="dipki::Ecc::DHSharedSecret"></a>[dipki::Ecc::DHSharedSecret](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#a641375295d539a47a74f1415cc62b126 "External link") - Compute EC Diffie-Hellman (ECDH) shared secret.
* <a id="dipki::Ecc::KeyHashCode"></a>[dipki::Ecc::KeyHashCode](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#ab038341ad84051f76c27a4961b899603 "External link") - Compute the hash code of an "internal" ECC public or private key string.
* <a id="dipki::Ecc::MakeKeys"></a>[dipki::Ecc::MakeKeys](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#a61c359b0da5243cb7e028d0a2e7cce08 "External link") - Generate an EC public/private key pair and save as two key files.
* <a id="dipki::Ecc::PublicKeyFromPrivate"></a>[dipki::Ecc::PublicKeyFromPrivate](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#a71a6adfb1db7101969d7b625b9d8d842 "External link") - Convert an internal EC private key string into an internal EC public key string.
* <a id="dipki::Ecc::QueryKey"></a>[dipki::Ecc::QueryKey](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#abe2d746ed26a73dc4404f59b96df7fd6 "External link") - Query an EC key string for selected information.
* <a id="dipki::Ecc::ReadKeyByCurve"></a>[dipki::Ecc::ReadKeyByCurve](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#a9201fbe6d4b6b5a45c47b3865253ce7e "External link") - Read an EC key from its hexadecimal representation.
* <a id="dipki::Ecc::ReadPrivateKey"></a>[dipki::Ecc::ReadPrivateKey](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#a7ab4058c743e56c7e14ecd7812cd8173 "External link") - Read from a file or a string containing an EC private key into an "internal" private key string.
* <a id="dipki::Ecc::ReadPublicKey"></a>[dipki::Ecc::ReadPublicKey](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#af296521d6be949c86bb388db37750c99 "External link") - Read from a file or a string containing an EC public key into an "internal" public key string.
* <a id="dipki::Ecc::SaveEncKey"></a>[dipki::Ecc::SaveEncKey](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#a069ed15422bafa4f727e6219de02ef64 "External link") - Save an internal EC private key string to an encrypted private key file.
* <a id="dipki::Ecc::SaveKey"></a>[dipki::Ecc::SaveKey](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ecc.html#a555d6cf01c2630f0e225198723b9518b "External link") - Save an internal EC key string (public or private) to an unencrypted key file.
* <a id="dipki::Err::ErrorLookup"></a>[dipki::Err::ErrorLookup](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_err.html#ad218a5ca4591b58f1b0cf2a1a853f402 "External link") - Look up description for error code.
* <a id="dipki::Err::FormatErrorMessage"></a>[dipki::Err::FormatErrorMessage](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_err.html#a27fe49e87703af2c7935028497bbadde "External link") - Return an error message string for the last error.
* <a id="dipki::Err::LastError"></a>[dipki::Err::LastError](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_err.html#a8df1f51e1ffacd29e58a610c0a5ae58d "External link") - Retrieve the last error message (if available).
* <a id="dipki::Gen::CompileTime"></a>[dipki::Gen::CompileTime](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_gen.html#a732f1c215c41715dae749f05ef1e5e7c "External link") - Get date and time the core native DLL module was last compiled.
* <a id="dipki::Gen::LicenceType"></a>[dipki::Gen::LicenceType](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_gen.html#a740d056f996720c32bb48d6c9a80883a "External link") - Get licence type as a string.
* <a id="dipki::Gen::ModuleInfo"></a>[dipki::Gen::ModuleInfo](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_gen.html#a131219a3f8ad6f704d9b34dcfd041088 "External link") - Get information about the core module.
* <a id="dipki::Gen::ModuleName"></a>[dipki::Gen::ModuleName](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_gen.html#a1dab5a1f9481bc2e9d03b241707c8b41 "External link") - Get full path name of the current process's core native DLL.
* <a id="dipki::Gen::Platform"></a>[dipki::Gen::Platform](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_gen.html#af2e8acdc25d91b79ba5603088108f984 "External link") - Get platform the core native DLL was compiled for.
* <a id="dipki::Gen::Version"></a>[dipki::Gen::Version](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_gen.html#a5274e15a8183189f52b300e807037756 "External link") - Get version number of the core native DLL as an integer value.
* <a id="dipki::Hash::AlgName"></a>[dipki::Hash::AlgName](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hash.html#ae18e18be1d74c32bc18819e991cba14e "External link") - Get the algorithm name.
* <a id="dipki::Hash::Bytes"></a>[dipki::Hash::Bytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hash.html#ad7b2346b1e672cda85f4685feeb4e851 "External link") - Compute hash digest over byte array.
* <a id="dipki::Hash::Double"></a>[dipki::Hash::Double](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hash.html#a91567bb5268d8410b8709e7cf37da0d2 "External link") - Create double hash (hash of hash).
* <a id="dipki::Hash::File"></a>[dipki::Hash::File](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hash.html#a02207143699c3b81a57b54ffc8bc1729 "External link") - Compute hash digest over a binary file.
* <a id="dipki::Hash::HashAlgFromString"></a>[dipki::Hash::HashAlgFromString](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hash.html#a50c19afc2443b66393786d2f0a124cf5 "External link") - Get hash algorithm from a string.
* <a id="dipki::Hash::HexFromBytes"></a>[dipki::Hash::HexFromBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hash.html#ad21a696ec3eadb80d1f362c5ad7fc0f8 "External link") - Compute hash digest in hex format over byte array.
* <a id="dipki::Hash::HexFromFile"></a>[dipki::Hash::HexFromFile](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hash.html#a20201d2aa3e4eb8372616ff1d3a0361c "External link") - Compute hash digest in hex format over a file.
* <a id="dipki::Hash::HexFromHex"></a>[dipki::Hash::HexFromHex](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hash.html#a32622d3a194234770744e300db0215f0 "External link") - Compute hash digest in hex format over hex-encoded input.
* <a id="dipki::Hash::HexFromString"></a>[dipki::Hash::HexFromString](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hash.html#aac1ec55a49cad50c09a8cc2ff7efcd6b "External link") - Compute hash digest in hex format over string input.
* <a id="dipki::Hash::Length"></a>[dipki::Hash::Length](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hash.html#a14f9dc55c1f84a66f7729b64e70dd740 "External link") - Return length of message digest output in bytes.
* <a id="dipki::Hmac::Bytes"></a>[dipki::Hmac::Bytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hmac.html#ae6e138b6d6c13d03e2dbd2953a03c902 "External link") - Compute HMAC over byte array.
* <a id="dipki::Hmac::HexFromBytes"></a>[dipki::Hmac::HexFromBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hmac.html#a42d50f89e1642e1256c499bfb3c93863 "External link") - Compute HMAC in hex format over byte array.
* <a id="dipki::Hmac::HexFromHex"></a>[dipki::Hmac::HexFromHex](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hmac.html#aedb10f9b3b1e3c29b10c39a4534fb60a "External link") - Compute HMAC in hex format over hex-encoded input.
* <a id="dipki::Hmac::HexFromString"></a>[dipki::Hmac::HexFromString](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hmac.html#ac3bf0896a57165b5be3a319aa4095f02 "External link") - Compute HMAC in hex format over string input.
* <a id="dipki::Hpke::DerivePrivateKey"></a>[dipki::Hpke::DerivePrivateKey](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hpke.html#a5897999f600ef45d4c8da7217d712c5e "External link") - Derive an EC private key in a deterministic manner from input keying material using the DeriveKeyPair algorithm in RFC9180.
* <a id="dipki::Hpke::LabeledExpand"></a>[dipki::Hpke::LabeledExpand](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hpke.html#a2fc65341143e165391f69aebf5950541 "External link") - Compute the output of the LabeledExpand function as defined in RFC9180.
* <a id="dipki::Hpke::LabeledExtract"></a>[dipki::Hpke::LabeledExtract](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_hpke.html#a27d47d152488346f40b650cdf6063b88 "External link") - Compute the output of the LabeledExtract function as defined in RFC9180.
* <a id="dipki::Kdf::Bytes"></a>[dipki::Kdf::Bytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_kdf.html#ad3196c7ce3cf9588c27782d2c1e7ede9 "External link") - Generate a key-encryption key (KEK) from input keying material (IKM) using a key derivation function (KDF).
* <a id="dipki::Kdf::ForCms"></a>[dipki::Kdf::ForCms](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_kdf.html#a646a8ea8e026b47e4177950ccfe2159a "External link") - Generate a key-encryption key (KEK) for ECDH key exchange in a CMS EnvelopedData object.
* <a id="dipki::Ocsp::MakeRequest"></a>[dipki::Ocsp::MakeRequest](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ocsp.html#af639efb0c08004ee072481faa28393ac "External link") - Create an Online Certification Status Protocol (OCSP) request as a base64 string.
* <a id="dipki::Ocsp::ReadResponse"></a>[dipki::Ocsp::ReadResponse](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_ocsp.html#a0e078b975897cfd0433904c61959dc76 "External link") - Read a response to an Online Certification Status Protocol (OCSP) request and outputs the main results in text form.
* <a id="dipki::Pbe::Kdf2"></a>[dipki::Pbe::Kdf2](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_pbe.html#a1ad12199140373ac7a6dbbf4a936ce65 "External link") - Derive a key of any length from a password using the PBKDF2 algorithm from PKCS #5 v2.1.
* <a id="dipki::Pbe::Scrypt"></a>[dipki::Pbe::Scrypt](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_pbe.html#a802fc639667ab1999be8e1c19cf16cd1 "External link") - Derive a key of any length from a password using the SCRYPT algorithm from RFC7914.
* <a id="dipki::Pem::FileFromBinFile"></a>[dipki::Pem::FileFromBinFile](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_pem.html#a94dbda8a7c4e2bf2292329e83fe245dc "External link") - Create a PEM file from a binary file.
* <a id="dipki::Pem::FileToBinFile"></a>[dipki::Pem::FileToBinFile](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_pem.html#a5c1beb5fe93e5e1ede340216f283f04d "External link") - Convert the contents of a PEM file into a binary file.
* <a id="dipki::Pfx::MakeFile"></a>[dipki::Pfx::MakeFile](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_pfx.html#a7a42e6bb9df32c43243b0d6910bded9b "External link") - Create a PFX (PKCS-12) file from an X.509 certificate and (optional) encrypted private key file.
* <a id="dipki::Pfx::SignatureIsValid"></a>[dipki::Pfx::SignatureIsValid](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_pfx.html#a26bbea62dceae2f6994049f79a7e8706 "External link") - Verify the MacData signature in a PKCS-12 file.
* <a id="dipki::Prf::Bytes"></a>[dipki::Prf::Bytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_prf.html#ad1500746341457d180a3b9ba73424030 "External link") - Generate output bytes using a pseudorandom function (PRF).
* <a id="dipki::Pwd::Prompt"></a>[dipki::Pwd::Prompt](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_pwd.html#ac74618d08be72b6f619310ab30a6e03b "External link") - Open a dialog box to receive a password with user-supplied prompt.
* <a id="dipki::Rng::Bytes"></a>[dipki::Rng::Bytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rng.html#a387b33340abf4e1233426494059f61a9 "External link") - Generate an array of random bytes.
* <a id="dipki::Rng::Guid"></a>[dipki::Rng::Guid](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rng.html#a7388a8609da4617ca54662fe6093fd1a "External link") - Generate a random 36-character Global Unique IDentifier (GUID) string according to [RFC4122](https://datatracker.ietf.org/doc/html/rfc4122 "External link").
* <a id="dipki::Rng::Initialize"></a>[dipki::Rng::Initialize](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rng.html#a49d9a9c8d333976acfb17551bd22886d "External link") - Initialize the RNG generator using a seed file.
* <a id="dipki::Rng::InitializeEx"></a>[dipki::Rng::InitializeEx](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rng.html#a2c709f37337b06ac4fd16c25c7682ffd "External link") - Query and initialize the RNG generator using Intel(R) DRNG, if available.
* <a id="dipki::Rng::Number"></a>[dipki::Rng::Number](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rng.html#a07289bae32a6ddd89da54a4c20a3c85d "External link") - Generate a random integer in a given range.
* <a id="dipki::Rng::Octet"></a>[dipki::Rng::Octet](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rng.html#af53eacf51dd6fcb08333fea515c7cbc6 "External link") - Generate a single random octet (byte)
* <a id="dipki::Rng::UpdateSeedFile"></a>[dipki::Rng::UpdateSeedFile](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rng.html#ac97be2de93aab03d4caee358b0410bd8 "External link") - Update the RNG seed file with more entropy.
* <a id="dipki::Rsa::DecodeMsgForEncryption"></a>[dipki::Rsa::DecodeMsgForEncryption](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a9d25f8de0a038b0aa9b23c80f2f40b26 "External link") - Decode a message for encryption.
* <a id="dipki::Rsa::DecodeMsgForSignature"></a>[dipki::Rsa::DecodeMsgForSignature](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a192f8d5de70c1eaa23720cd73f584697 "External link") - Extract digest (or digestinfo) from an EMSA-PKCS1-v1_5-encoded block.
* <a id="dipki::Rsa::Decrypt"></a>[dipki::Rsa::Decrypt](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#af10a5292171c8e7388e1de5a0231ade4 "External link") - Decrypt a message encrypted using an RSA encryption scheme.
* <a id="dipki::Rsa::EncodeMsgForEncryption"></a>[dipki::Rsa::EncodeMsgForEncryption](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a8a19ba663e9d41954b32f6e7ef82ab89 "External link") - Encode a message for encryption.
* <a id="dipki::Rsa::EncodeMsgForSignature"></a>[dipki::Rsa::EncodeMsgForSignature](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#ae0c921a06ec0cb1e7a12a44e92887646 "External link") - Encode a message for signature.
* <a id="dipki::Rsa::Encrypt"></a>[dipki::Rsa::Encrypt](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a7a1985fcfbb3e85601fb5b45242669b6 "External link") - Encrypt a short message using RSA encryption.
* <a id="dipki::Rsa::FromXMLString"></a>[dipki::Rsa::FromXMLString](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#abe9c8f1422fc92c7539cdaa7abe65717 "External link") - Return an RSA key string in internal format from an XML string.
* <a id="dipki::Rsa::GetPrivateKeyFromPFX"></a>[dipki::Rsa::GetPrivateKeyFromPFX](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a238dd633405d9a5174a6a1762db151e7 "External link") - Extract an encrypted private key from a PKCS-12 PKCS8ShroudedKeyBag, saving the output directly as a new file.
* <a id="dipki::Rsa::KeyBits"></a>[dipki::Rsa::KeyBits](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a6f495276f394a1eb0764e67c7d710206 "External link") - Get number of significant bits in RSA key modulus.
* <a id="dipki::Rsa::KeyBytes"></a>[dipki::Rsa::KeyBytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a2f98ec43d53954c0eff33559b9ab07de "External link") - Get number of bytes (octets) in RSA key modulus.
* <a id="dipki::Rsa::KeyHashCode"></a>[dipki::Rsa::KeyHashCode](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a2a29511d1ba843a5024f1f5e4fc1dc16 "External link") - Compute the hash code of an "internal" RSA public or private key string.
* <a id="dipki::Rsa::KeyIsPrivate"></a>[dipki::Rsa::KeyIsPrivate](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a6978884750ddf44b09f4c71437034335 "External link") - Determine if keystring is a private key.
* <a id="dipki::Rsa::KeyMatch"></a>[dipki::Rsa::KeyMatch](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a50c94da4020db9255ef92080d6d4fe52 "External link") - Determine if a pair of "internal" RSA private and public key strings are matched.
* <a id="dipki::Rsa::KeyValue"></a>[dipki::Rsa::KeyValue](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a128b7ef2bae278e6b0856439e43d2e8d "External link") - Extract a base64-encoded RSA key value from internal key string.
* <a id="dipki::Rsa::MakeKeys"></a>[dipki::Rsa::MakeKeys](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a48dfe8237977369f90405443169a1bce "External link") - Generate an RSA public/private key pair and save as two key files.
* <a id="dipki::Rsa::PublicKeyFromPrivate"></a>[dipki::Rsa::PublicKeyFromPrivate](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a32a2360cf76e4930b1a55950afdc6da4 "External link") - Get internal RSA public key string from an internal RSA private key string.
* <a id="dipki::Rsa::RawPrivate"></a>[dipki::Rsa::RawPrivate](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a50a88a4e9650c3e384e25135eb8e6dd5 "External link") - Transforms (that is, encrypts or decrypts) raw data using an RSA private key.
* <a id="dipki::Rsa::RawPublic"></a>[dipki::Rsa::RawPublic](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#aa9095099ada24c1489840cfa53ec83e3 "External link") - Transforms (that is, encrypts or decrypts) raw data using an RSA public key.
* <a id="dipki::Rsa::ReadPrivateKey"></a>[dipki::Rsa::ReadPrivateKey](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a1e2eff6eac9764624ed7d9eaf23b8f7a "External link") - Read from a file or string containing a private key into an "internal" key string.
* <a id="dipki::Rsa::ReadPublicKey"></a>[dipki::Rsa::ReadPublicKey](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a2d73a8d0f5c72a5c8328d290351bedb6 "External link") - Read from a file or string containing a public key into an "internal" key string.
* <a id="dipki::Rsa::SaveEncKey"></a>[dipki::Rsa::SaveEncKey](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a444982f3c1f80e8971f464eac6f47a26 "External link") - Save an internal RSA key string to an encrypted key file.
* <a id="dipki::Rsa::SaveKey"></a>[dipki::Rsa::SaveKey](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a2ce90bf0f13cbb2098a34b838f7f1af2 "External link") - Save an internal RSA key string to a key file.
* <a id="dipki::Rsa::ToXMLString"></a>[dipki::Rsa::ToXMLString](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_rsa.html#a33afa8224f6a3d5a3142eddb9e223b70 "External link") - Return an XML string representation of an RSA internal key string.
* <a id="dipki::Sig::AlgName"></a>[dipki::Sig::AlgName](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_sig.html#a9d41e8ab8d866dc5e3bb8ba3725fced8 "External link") - Get the algorithm name.
* <a id="dipki::Sig::GetHashNameFromSigAlg"></a>[dipki::Sig::GetHashNameFromSigAlg](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_sig.html#a397c5d60ef2db934035707797b10437e "External link") - Get the hash algorithm used in the signature algorithm.
* <a id="dipki::Sig::SignData"></a>[dipki::Sig::SignData](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_sig.html#a782ee97d4d716ecdc933e4bc1c9ec36c "External link") - Compute a signature value over data in a byte array.
* <a id="dipki::Sig::SignDigest"></a>[dipki::Sig::SignDigest](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_sig.html#adfc0752234cfe2bbd9f52f7b2e35edfd "External link") - Compute a signature value over a message digest value.
* <a id="dipki::Sig::SignFile"></a>[dipki::Sig::SignFile](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_sig.html#aa011b65674d1c69b7ca1aafbb67fd0e0 "External link") - Compute a signature value over binary data in a file.
* <a id="dipki::Sig::VerifyData"></a>[dipki::Sig::VerifyData](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_sig.html#afc0d9cb74fe7cfb2ce610f5f9c8c74fc "External link") - Verify a signature value over data in a byte array.
* <a id="dipki::Sig::VerifyDigest"></a>[dipki::Sig::VerifyDigest](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_sig.html#a3c07eea0283ab8fcbafc9d8300a5f933 "External link") - Verify a signature value over a message digest value of data.
* <a id="dipki::Sig::VerifyFile"></a>[dipki::Sig::VerifyFile](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_sig.html#a4434b77b3411712a19c8cbfc0109c3ea "External link") - Verify a signature value over data in a file.
* <a id="dipki::Smime::Extract"></a>[dipki::Smime::Extract](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_smime.html#a440c2d87ffd605a72a6ff1ee2e6b419f "External link") - Extract the body from an S/MIME entity.
* <a id="dipki::Smime::Query"></a>[dipki::Smime::Query](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_smime.html#a1f6f809a61f7ac1b8680ffdf242a6757 "External link") - Query an S/MIME entity for selected information.
* <a id="dipki::Smime::Wrap"></a>[dipki::Smime::Wrap](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_smime.html#a10d307291729cb54cdfdc5f4c11f3469 "External link") - Wrap a CMS object in an S/MIME entity.
* <a id="dipki::Wipe::Data"></a>[dipki::Wipe::Data](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_wipe.html#a6d3d230ff058e62ad26ec96f5b44d5d5 "External link") - Zeroise then clear data in memory.
* <a id="dipki::Wipe::File"></a>[dipki::Wipe::File](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_wipe.html#a487b2823f03489759882f38617e15020 "External link") - Securely wipe and delete a file.
* <a id="dipki::Wipe::String"></a>[dipki::Wipe::String](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_wipe.html#a7f4bcf4a0356d51efe7788b360bab3d4 "External link") - Zeroise then clear a string.
* <a id="dipki::X509::CertIsRevoked"></a>[dipki::X509::CertIsRevoked](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a32ce1e27f5d4ab8bc3fc795384439e8f "External link") - Check whether an X.509 certificate has been revoked in a given Certificate Revocation List (CRL).
* <a id="dipki::X509::CertIsValidNow"></a>[dipki::X509::CertIsValidNow](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#ac6ef066faf9ca7d9c4e5b7d7d5a04973 "External link") - Verify that an X.509 certificate is currently valid as per system clock.
* <a id="dipki::X509::CertIsVerified"></a>[dipki::X509::CertIsVerified](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a1532cfaef52bef714697a6728ee10c75 "External link") - Verify that an X.509 certificate has been signed by its issuer.
* <a id="dipki::X509::CertPathIsValid"></a>[dipki::X509::CertPathIsValid](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a32b16ee531722c941cce3eef8b9209d1 "External link") - Validate a certificate path.
* <a id="dipki::X509::CertRequest"></a>[dipki::X509::CertRequest](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#af0c4852b7eb96fe4be27dbb5eb738855 "External link") - Create a PKCS #10 certificate signing request (CSR).
* <a id="dipki::X509::CertThumb"></a>[dipki::X509::CertThumb](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a42640b33c3c4c2745644b2c3f067ed21 "External link") - Calculate the thumbprint (message digest hash) of an X.509 certificate.
* <a id="dipki::X509::GetCertCountInP7Chain"></a>[dipki::X509::GetCertCountInP7Chain](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#ab39028867279fae0db82bd281caedbc1 "External link") - Return number of certificates in a PKCS-7 "certs-only" certificate chain file.
* <a id="dipki::X509::GetCertFromP7Chain"></a>[dipki::X509::GetCertFromP7Chain](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a08efea2f2eb7412bdbc0c47c9af25341 "External link") - Extract an X.509 certificate from a PKCS-7 "certs-only" certificate chain file, saving the output directly as a new file.
* <a id="dipki::X509::GetCertFromPFX"></a>[dipki::X509::GetCertFromPFX](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a203c6c2df25242677aed1b245d945bfa "External link") - Extract an X.509 certificate from a PKCS-12 PFX/.p12 file, saving the output directly as a new file.
* <a id="dipki::X509::GetP7ChainFromPFX"></a>[dipki::X509::GetP7ChainFromPFX](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a3f55148aa5a2906b853b9ee95709779b "External link") - Extract all X.509 certificates from a PKCS-12 PFX/.p12 file, saving the output directly as a new PKCS-7 "certs-only" certificate chain file.
* <a id="dipki::X509::HashIssuerAndSN"></a>[dipki::X509::HashIssuerAndSN](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#aab9ad8e8fa8aadf6df0c37c8a3ea89e1 "External link") - Return the hash of the issuer and serial number.
* <a id="dipki::X509::MakeCRL"></a>[dipki::X509::MakeCRL](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a8c1e71c90536e86f8f45a1f22af57d05 "External link") - Create an X.509 Certificate Revocation List (CRL).
* <a id="dipki::X509::MakeCert"></a>[dipki::X509::MakeCert](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#abc55dc55d87795a5eec2c6a2754d57ec "External link") - Create an X.509 certificate using subject's public key and issuer's private key.
* <a id="dipki::X509::MakeCertSelf"></a>[dipki::X509::MakeCertSelf](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a8f3dcd821cf4e2e614f9b859ffc8e675 "External link") - Create a self-signed X.509 certificate.
* <a id="dipki::X509::QueryCert"></a>[dipki::X509::QueryCert](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#ac7b07eccfbb6ed11d98abd9808119633 "External link") - Query an X.509 certificate file for selected information.
* <a id="dipki::X509::ReadCertStringFromP7Chain"></a>[dipki::X509::ReadCertStringFromP7Chain](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a340373ecfdf7a3d6560ef7f3829ad913 "External link") - Read an X.509 certificate into a base64 string from a PKCS-7 "certs-only" certificate chain file.
* <a id="dipki::X509::ReadCertStringFromPFX"></a>[dipki::X509::ReadCertStringFromPFX](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a737485c8b333f51e80f7eab8ca4dc978 "External link") - Read an X.509 certificate into a base64 string from PKCS-12 PFX/.p12 data.
* <a id="dipki::X509::ReadStringFromFile"></a>[dipki::X509::ReadStringFromFile](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a44e353950105afd924a2b2cdede7e956 "External link") - Read an X.509 certificate into its base64 string representation.
* <a id="dipki::X509::SaveFileFromString"></a>[dipki::X509::SaveFileFromString](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#aafcc3aa7a6a076b7f8f4dcb207e62fe4 "External link") - Create an X.509 certificate file from its base64 string representation.
* <a id="dipki::X509::TextDumpToString"></a>[dipki::X509::TextDumpToString](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_x509.html#a9b8039568d9cd27430a5809956f06ed4 "External link") - Dump details of an X.509 certificate or a X.509 certificate revocation list (CRL) or a PKCS-10 certificate signing request (CSR) to a string.
* <a id="dipki::Xof::Bytes"></a>[dipki::Xof::Bytes](https://cryptosys.net/pki/cpppki/html/classdipki_1_1_xof.html#a55cd586acc417fe248d8568bed801766 "External link") - Generate bytes using an extendable-output function (XOF).

[[Contents](#topofpage)] [[Index](#index)]

<a id="dotnetclassesandmethods"></a>.NET Classes and Methods
------------------------------------------------------------

To program in the .NET languages C# and `VB.NET` (VB20xx), use the classes and methods in the
CryptoSys PKI Pro .NET Class Library `diCrSysPKINet.dll`.

There is a full listing of all the .NET methods at [List of .NET Methods](#methodlist).

For more guidance on programming, see [Using with .NET: C# and `VB.NET`](#UsingWithDotNet).

[[Contents](#topofpage)] [[Index](#index)]

### <a id="xrefdotnet"></a>Cross-reference between Functions and .NET Methods

The following table shows the cross-reference between the core VB6/C functions and the .NET methods.
Plus, where relevant, the equivalent [VBA wrapper function](#vbawrapperfunctions).

| Function | Equivalent .NET Method | VBA Wrapper |
| --- | --- | --- |
| [`ASN1_TextDump`](#ASN1_TextDump) | [Asn1.TextDump Method](#M_Asn1_TextDump) |  |
| [`ASN1_TextDumpToString`](#ASN1_TextDumpToString) | [Asn1.TextDumpToString Method](#M_Asn1_TextDumpToString) | `[asn1TextDumpToString](#VB_asn1TextDumpToString)` |
| [`ASN1_Type`](#ASN1_Type) | [Asn1.Type Method](#M_Asn1_Type) | `[asn1Type](#VB_asn1Type)` |
| [`CIPHER_Bytes`](#CIPHER_Bytes) - @deprecated | [Cipher.Encrypt Method](#M_Cipher_Encrypt_ByteByteByteCipherAlgorithmMode) (Byte[], Byte[], Byte[], CipherAlgorithm, Mode) [Cipher.Decrypt Method](#M_Cipher_Decrypt_ByteByteByteCipherAlgorithmMode) (Byte[], Byte[], Byte[], CipherAlgorithm, Mode) |  |
| [`CIPHER_DecryptAEAD`](#CIPHER_DecryptAEAD) | [Cipher.DecryptAEAD Method](#M_Cipher_DecryptAEAD_ByteByteByteAeadAlgorithm) (Byte[], Byte[], Byte[], AeadAlgorithm) [Cipher.DecryptAEAD Method](#M_Cipher_DecryptAEAD_ByteByteByteByteAeadAlgorithmCipher_Opts) (Byte[], Byte[], Byte[], Byte[], AeadAlgorithm, Cipher.Opts) | `[cipherDecryptAEAD](#VB_cipherDecryptAEAD)` |
| [`CIPHER_DecryptBytes`](#CIPHER_DecryptBytes) | [Cipher.Decrypt Method](#M_Cipher_Decrypt_ByteByteByteCipherAlgorithmModePaddingCipher_Opts) (Byte[], Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts) | `[cipherDecryptBytes](#VB_cipherDecryptBytes)` |
| [`CIPHER_DecryptHex`](#CIPHER_DecryptHex) | [Cipher.Decrypt Method](#M_Cipher_Decrypt_StringStringStringCipherAlgorithmModePaddingCipher_Opts) (String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts) | `[cipherDecryptHex](#VB_cipherDecryptHex)` |
| [`CIPHER_EncryptAEAD`](#CIPHER_EncryptAEAD) | [Cipher.EncryptAEAD Method](#M_Cipher_EncryptAEAD_ByteByteByteAeadAlgorithm) (Byte[], Byte[], Byte[], AeadAlgorithm) [Cipher.EncryptAEAD Method](#M_Cipher_EncryptAEAD_ByteByteByteByteAeadAlgorithmCipher_Opts) (Byte[], Byte[], Byte[], Byte[], AeadAlgorithm, Cipher.Opts) | `[cipherEncryptAEAD](#VB_cipherEncryptAEAD)` |
| [`CIPHER_EncryptBytes`](#CIPHER_EncryptBytes) | [Cipher.Encrypt Method](#M_Cipher_Encrypt_ByteByteByteCipherAlgorithmModePaddingCipher_Opts) (Byte[], Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts) | `[cipherEncryptBytes](#VB_cipherEncryptBytes)` |
| [`CIPHER_EncryptHex`](#CIPHER_EncryptHex) | [Cipher.Encrypt Method](#M_Cipher_Encrypt_StringStringStringCipherAlgorithmModePaddingCipher_Opts) (String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts) | `[cipherEncryptHex](#VB_cipherEncryptHex)` |
| [`CIPHER_File`](#CIPHER_File) - @deprecated | [Cipher.FileEncrypt Method](#M_Cipher_FileEncrypt_StringStringByteByteCipherAlgorithmModePaddingCipher_Opts) [Cipher.FileDecrypt Method](#M_Cipher_FileDecrypt_StringStringByteByteCipherAlgorithmModePaddingCipher_Opts) |  |
| [`CIPHER_FileDecrypt`](#CIPHER_FileDecrypt) | [Cipher.FileDecrypt Method](#M_Cipher_FileDecrypt_StringStringByteByteCipherAlgorithmModePaddingCipher_Opts) (String, String, Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts) [Cipher.FileDecrypt Method](#M_Cipher_FileDecrypt_StringStringStringStringCipherAlgorithmModePaddingCipher_Opts) (String, String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts) | `[cipherFileDecrypt](#VB_cipherFileDecrypt)` |
| [`CIPHER_FileEncrypt`](#CIPHER_FileEncrypt) | [Cipher.FileEncrypt Method](#M_Cipher_FileEncrypt_StringStringByteByteCipherAlgorithmModePaddingCipher_Opts) (String, String, Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts) [Cipher.FileEncrypt Method](#M_Cipher_FileEncrypt_StringStringStringStringCipherAlgorithmModePaddingCipher_Opts) (String, String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts) | `[cipherFileEncrypt](#VB_cipherFileEncrypt)` |
| [`CIPHER_Hex`](#CIPHER_Hex) | [Cipher.Encrypt Method](#M_Cipher_Encrypt_StringStringStringCipherAlgorithmMode) (String, String, String, CipherAlgorithm, Mode) [Cipher.Decrypt Method](#M_Cipher_Decrypt_StringStringStringCipherAlgorithmMode) (String, String, String, CipherAlgorithm, Mode) |  |
| [`CIPHER_KeyUnwrap`](#CIPHER_KeyUnwrap) | [Cipher.KeyUnwrap Method](#M_Cipher_KeyUnwrap) | `[cipherKeyUnwrap](#VB_cipherKeyUnwrap)` |
| [`CIPHER_KeyWrap`](#CIPHER_KeyWrap) | [Cipher.KeyWrap Method](#M_Cipher_KeyWrap) | `[cipherKeyWrap](#VB_cipherKeyWrap)` |
| [`CMS_GetSigDataDigest`](#CMS_GetSigDataDigest) | [Cms.GetSigDataDigest Method](#M_Cms_GetSigDataDigest) | `[cmsGetSigDataDigest](#VB_cmsGetSigDataDigest)` |
| [`CMS_MakeComprData`](#CMS_MakeComprData) | [Cms.MakeComprData Method](#M_Cms_MakeComprData) |  |
| [`CMS_MakeDetachedSig`](#CMS_MakeDetachedSig) | [Cms.MakeDetachedSig Method](#M_Cms_MakeDetachedSig) |  |
| [`CMS_MakeEnvData`](#CMS_MakeEnvData) | [Cms.MakeEnvData Method](#M_Cms_MakeEnvData_StringStringStringCipherAlgorithmCms_EnvDataOptions) ( String, String, String, CipherAlgorithm, Cms.EnvDataOptions ) [Cms.MakeEnvData Method](#M_Cms_MakeEnvData_StringStringStringCipherAlgorithmCms_KeyEncrAlgorithmHashAlgorithmCms_EnvDataOptionsKdf_KdfAlgKdf_KeyWrapAlgStringInt32Cms_ContentEncrAlg) ( String, String, String, CipherAlgorithm, Cms.KeyEncrAlgorithm, HashAlgorithm, Cms.EnvDataOptions, KdfAlg, KeyWrapAlg, String, Int32, Cms.ContentEncrAlg) | `[cmsMakeEnvData](#VB_cmsMakeEnvData)` |
| [`CMS_MakeEnvDataFromBytes`](#CMS_MakeEnvDataFromBytes) | [Cms.MakeEnvDataFromBytes Method](#M_Cms_MakeEnvDataFromBytes) | `[cmsMakeEnvDataFromBytes](#VB_cmsMakeEnvDataFromBytes)` |
| [`CMS_MakeEnvDataFromString`](#CMS_MakeEnvDataFromString) | [Cms.MakeEnvDataFromString Method](#M_Cms_MakeEnvDataFromString_StringStringStringCipherAlgorithmCms_EnvDataOptions) (String, String, String, CipherAlgorithm, Cms.EnvDataOptions) [Cms.MakeEnvDataFromString Method](#M_Cms_MakeEnvDataFromString_StringStringStringCipherAlgorithmCms_KeyEncrAlgorithmHashAlgorithmCms_EnvDataOptionsKdf_KdfAlgKdf_KeyWrapAlgStringInt32Cms_ContentEncrAlg) (String, String, String, CipherAlgorithm, Cms.KeyEncrAlgorithm, HashAlgorithm, Cms.EnvDataOptions, KdfAlg, KeyWrapAlg, String, Int32, Cms.ContentEncrAlg) | `[cmsMakeEnvDataFromString](#VB_cmsMakeEnvDataFromString)` |
| [`CMS_MakeSigData`](#CMS_MakeSigData) | [Cms.MakeSigData Method](#M_Cms_MakeSigData_StringStringStringStringCms_SigAlgCms_SigDataOptions) ( String, String, String, String, Cms.SigAlg, Cms.SigDataOptions) [Cms.MakeSigData Method](#M_Cms_MakeSigData_StringStringStringStringHashAlgorithmCms_SigDataOptions) ( String, String, String, String, HashAlgorithm, Cms.SigDataOptions) |  |
| [`CMS_MakeSigDataFromBytes`](#CMS_MakeSigDataFromBytes) | [Cms.MakeSigDataFromBytes Method](#M_Cms_MakeSigDataFromBytes) | `[cmsMakeSigDataFromBytes](#VB_cmsMakeSigDataFromBytes)` |
| [`CMS_MakeSigDataFromSigValue`](#CMS_MakeSigDataFromSigValue) | [Cms.MakeSigDataFromSigValue Method](#M_Cms_MakeSigDataFromSigValue) [Cms.MakeSigDataFromPseudo Method](#M_Cms_MakeSigDataFromPseudo) | `[cmsMakeSigDataFromSigValue](#VB_cmsMakeSigDataFromSigValue)` |
| [`CMS_MakeSigDataFromString`](#CMS_MakeSigDataFromString) | [Cms.MakeSigDataFromString Method](#M_Cms_MakeSigDataFromString_StringStringStringStringCms_SigAlgCms_SigDataOptions) (String, String, String, String, Cms.SigAlg, Cms.SigDataOptions) [Cms.MakeSigDataFromString Method](#M_Cms_MakeSigDataFromString_StringStringStringStringHashAlgorithmCms_SigDataOptions) (String, String, String, String, HashAlgorithm, Cms.SigDataOptions) |  |
| [`CMS_QueryEnvData`](#CMS_QueryEnvData) | [Cms.QueryEnvData Method](#M_Cms_QueryEnvData) | `[cmsQueryEnvData](#VB_cmsQueryEnvData)` |
| [`CMS_QuerySigData`](#CMS_QuerySigData) | [Cms.QuerySigData Method](#M_Cms_QuerySigData) | `[cmsQuerySigData](#VB_cmsQuerySigData)` |
| [`CMS_ReadComprData`](#CMS_ReadComprData) | [Cms.ReadComprData Method](#M_Cms_ReadComprData) |  |
| [`CMS_ReadEnvData`](#CMS_ReadEnvData) | [Cms.ReadEnvDataToFile Method](#M_Cms_ReadEnvDataToFile) |  |
| [`CMS_ReadEnvDataToBytes`](#CMS_ReadEnvDataToBytes) | [Cms.ReadEnvDataToBytes Method](#M_Cms_ReadEnvDataToBytes) | `[cmsReadEnvDataToBytes](#VB_cmsReadEnvDataToBytes)` |
| [`CMS_ReadEnvDataToString`](#CMS_ReadEnvDataToString) | [Cms.ReadEnvDataToString Method](#M_Cms_ReadEnvDataToString) | `[cmsReadEnvDataToString](#VB_cmsReadEnvDataToString)` |
| [`CMS_ReadSigData`](#CMS_ReadSigData) | [Cms.ReadSigDataToFile Method](#M_Cms_ReadSigDataToFile) |  |
| [`CMS_ReadSigDataToBytes`](#CMS_ReadSigDataToBytes) | [Cms.ReadSigDataToBytes Method](#M_Cms_ReadSigDataToBytes) | `[cmsReadSigDataToBytes](#VB_cmsReadSigDataToBytes)` |
| [`CMS_ReadSigDataToString`](#CMS_ReadSigDataToString) | [Cms.ReadSigDataToString Method](#M_Cms_ReadSigDataToString) | `[cmsReadSigDataToString](#VB_cmsReadSigDataToString)` |
| [`CMS_VerifySigData`](#CMS_VerifySigData) | [Cms.VerifySigData Method](#M_Cms_VerifySigData) | `[cmsVerifySigData](#VB_cmsVerifySigData)` |
| [`CNV_B64Filter`](#CNV_B64Filter) | [Cnv.Base64Filter Method](#M_Cnv_Base64Filter) | `[cnvB64Filter](#VB_cnvB64Filter)` |
| [`CNV_B64StrFromBytes`](#CNV_B64StrFromBytes) | [Cnv.ToBase64 Method](#M_Cnv_ToBase64_Byte) (Byte[]) [Cnv.ToBase64 Method](#M_Cnv_ToBase64_String) (String) | `[cnvToBase64](#VB_cnvToBase64)` |
| [`CNV_Base58FromBytes`](#CNV_Base58FromBytes) | [Cnv.ToBase58 Method](#M_Cnv_ToBase58) | `[cnvBase58FromBytes](#VB_cnvBase58FromBytes)` |
| [`CNV_Base58ToBytes`](#CNV_Base58ToBytes) | [Cnv.FromBase58 Method](#M_Cnv_FromBase58) | `[cnvBase58ToBytes](#VB_cnvBase58ToBytes)` |
| [`CNV_ByteEncoding`](#CNV_ByteEncoding) | [Cnv.ByteEncoding Method](#M_Cnv_ByteEncoding) | `[cnvByteEncoding](#VB_cnvByteEncoding)` |
| [`CNV_BytesFromB64Str`](#CNV_BytesFromB64Str) | [Cnv.FromBase64 Method](#M_Cnv_FromBase64) | `[cnvFromBase64](#VB_cnvFromBase64)` |
| [`CNV_BytesFromHexStr`](#CNV_BytesFromHexStr) | [Cnv.FromHex Method](#M_Cnv_FromHex) | `[cnvFromHex](#VB_cnvFromHex)` |
| [`CNV_CheckUTF8`](#CNV_CheckUTF8) - @deprecated | Not applicable in .NET |  |
| [`CNV_CheckUTF8Bytes`](#CNV_CheckUTF8Bytes) | [Cnv.CheckUTF8 Method](#M_Cnv_CheckUTF8) (Byte[]) | `[cnvCheckUTF8Bytes](#VB_cnvCheckUTF8Bytes)` |
| [`CNV_CheckUTF8File`](#CNV_CheckUTF8File) | [Cnv.CheckUTF8File Method](#M_Cnv_CheckUTF8File) |  |
| [`CNV_HexFilter`](#CNV_HexFilter) | [Cnv.HexFilter Method](#M_Cnv_HexFilter) | `[cnvHexFilter](#VB_cnvHexFilter)` |
| [`CNV_HexStrFromBytes`](#CNV_HexStrFromBytes) | [Cnv.ToHex Method](#M_Cnv_ToHex_Byte) | `[cnvToHex](#VB_cnvToHex)` |
| [`CNV_Latin1FromUTF8`](#CNV_Latin1FromUTF8) - @deprecated | Not applicable in .NET |  |
| [`CNV_Latin1FromUTF8Bytes`](#CNV_Latin1FromUTF8Bytes) | Use `System.Text.Encoding.UTF8.GetString(bytes)`. | `[cnvLatin1FromUTF8Bytes](#VB_cnvLatin1FromUTF8Bytes)` |
| [`CNV_NumFromBytes`](#CNV_NumFromBytes) | [Cnv.NumFromBytes Method](#M_Cnv_NumFromBytes) | `[cnvNumFromBytes](#VB_cnvNumFromBytes)` |
| [`CNV_NumToBytes`](#CNV_NumToBytes) | [Cnv.NumToBytes Method](#M_Cnv_NumToBytes) | `[cnvNumToBytes](#VB_cnvNumToBytes)` |
| [`CNV_ReverseBytes`](#CNV_ReverseBytes) | [Cnv.ReverseBytes Method](#M_Cnv_ReverseBytes) | `[cnvReverseBytes](#VB_cnvReverseBytes)` |
| [`CNV_ShortPathName`](#CNV_ShortPathName) | [Cnv.ShortPathName Method](#M_Cnv_ShortPathName) |  |
| [`CNV_UTF8BytesFromLatin1`](#CNV_UTF8BytesFromLatin1) | Use `System.Text.Encoding.UTF8.GetBytes(Str)`. | `[cnvUTF8BytesFromLatin1](#VB_cnvUTF8BytesFromLatin1)` |
| [`CNV_UTF8FromLatin1`](#CNV_UTF8FromLatin1) - @deprecated | Not applicable in .NET |  |
| [`COMPR_Compress`](#COMPR_Compress) | [Compr.Compress Method](#M_Compr_Compress) | `[comprCompress](#VB_comprCompress)` |
| [`COMPR_Uncompress`](#COMPR_Uncompress) | [Compr.Uncompress Method](#M_Compr_Uncompress) | `[comprUncompress](#VB_comprUncompress)` |
| [`ECC_DHSharedSecret`](#ECC_DHSharedSecret) | [Ecc.DHSharedSecret Method](#M_Ecc_DHSharedSecret) | `[eccDHSharedSecret](#VB_eccDHSharedSecret)` |
| [`ECC_KeyHashCode`](#ECC_KeyHashCode) | [Ecc.KeyHashCode Method](#M_Ecc_KeyHashCode) | `[eccKeyHashCode](#VB_eccKeyHashCode)` |
| [`ECC_MakeKeys`](#ECC_MakeKeys) | [Ecc.MakeKeys Method](#M_Ecc_MakeKeys) | `[eccMakeKeys](#VB_eccMakeKeys)` |
| [`ECC_PublicKeyFromPrivate`](#ECC_PublicKeyFromPrivate) | [Ecc.PublicKeyFromPrivate Method](#M_Ecc_PublicKeyFromPrivate) | `[eccPublicKeyFromPrivate](#VB_eccPublicKeyFromPrivate)` |
| [`ECC_QueryKey`](#ECC_QueryKey) | [Ecc.QueryKey Method](#M_Ecc_QueryKey) | `[eccQueryKey](#VB_eccQueryKey)` |
| [`ECC_ReadKeyByCurve`](#ECC_ReadKeyByCurve) | [Ecc.ReadKeyByCurve Method](#M_Ecc_ReadKeyByCurve) | `[eccReadKeyByCurve](#VB_eccReadKeyByCurve)` |
| [`ECC_ReadPrivateKey`](#ECC_ReadPrivateKey) | [Ecc.ReadPrivateKey Method](#M_Ecc_ReadPrivateKey) | `[eccReadPrivateKey](#VB_eccReadPrivateKey)` |
| [`ECC_ReadPublicKey`](#ECC_ReadPublicKey) | [Ecc.ReadPublicKey Method](#M_Ecc_ReadPublicKey) | `[eccReadPublicKey](#VB_eccReadPublicKey)` |
| [`ECC_SaveEncKey`](#ECC_SaveEncKey) | [Ecc.SaveEncKey Method](#M_Ecc_SaveEncKey) | `[eccSaveEncKey](#VB_eccSaveEncKey)` |
| [`ECC_SaveKey`](#ECC_SaveKey) | [Ecc.SaveKey Method](#M_Ecc_SaveKey) | `[eccSaveKey](#VB_eccSaveKey)` |
| [`HASH_Bytes`](#HASH_Bytes) | [Hash.BytesFromBytes Method](#M_Hash_BytesFromBytes) [Hash.Double Method](#M_Hash_Double) | `[hashBytes](#VB_hashBytes)` |
| [`HASH_File`](#HASH_File) | [Hash.BytesFromFile Method](#M_Hash_BytesFromFile) | `[hashFile](#VB_hashFile)` |
| [`HASH_HexFromBytes`](#HASH_HexFromBytes) | [Hash.HexFromBytes Method](#M_Hash_HexFromBytes) [Hash.HexFromString Method](#M_Hash_HexFromString) | `[hashHexFromBytes](#VB_hashHexFromBytes)` |
| [`HASH_HexFromFile`](#HASH_HexFromFile) | [Hash.HexFromFile Method](#M_Hash_HexFromFile) [Hash.HexFromTextFile Method](#M_Hash_HexFromTextFile) | `[hashHexFromFile](#VB_hashHexFromFile)` |
| [`HASH_HexFromHex`](#HASH_HexFromHex) | [Hash.HexFromHex Method](#M_Hash_HexFromHex) | `[hashHexFromHex](#VB_hashHexFromHex)` |
| [`HASH_Length`](#HASH_Length) | [Hash.Length Method](#M_Hash_Length) | `[hashLength](#VB_hashLength)` |
| [`HMAC_Bytes`](#HMAC_Bytes) | [Hmac.BytesFromBytes Method](#M_Hmac_BytesFromBytes) | `[hmacBytes](#VB_hmacBytes)` |
| [`HMAC_HexFromBytes`](#HMAC_HexFromBytes) | [Hmac.HexFromBytes Method](#M_Hmac_HexFromBytes) | `[hmacHexFromBytes](#VB_hmacHexFromBytes)` |
| [`HMAC_HexFromHex`](#HMAC_HexFromHex) | [Hmac.HexFromHex Method](#M_Hmac_HexFromHex) | `[hmacHexFromHex](#VB_hmacHexFromHex)` |
| [`KDF_Bytes`](#KDF_Bytes) | [Kdf.Bytes Method](#M_Kdf_Bytes) | `[kdfBytes](#VB_kdfBytes)` |
| [`HPKE_DerivePrivateKey`](#HPKE_DerivePrivateKey) | [Hpke.DerivePrivateKey Method](#M_Hpke_DerivePrivateKey) | `[hpkeDerivePrivateKey](#VB_hpkeDerivePrivateKey)` |
| [`HPKE_LabeledExpand`](#HPKE_LabeledExpand) | [Hpke.LabeledExpand Method](#M_Hpke_LabeledExpand) | `[hpkeLabeledExpand](#VB_hpkeLabeledExpand)` |
| [`HPKE_LabeledExtract`](#HPKE_LabeledExtract) | [Hpke.LabeledExtract Method](#M_Hpke_LabeledExtract) | `[hpkeLabeledExtract](#VB_hpkeLabeledExtract)` |
| [`KDF_ForCms`](#KDF_ForCms) | [Kdf.ForCms Method](#M_Kdf_ForCms) | `[kdfForCms](#VB_kdfForCms)` |
| [`OCSP_MakeRequest`](#OCSP_MakeRequest) | [Ocsp.MakeRequest Method](#M_Ocsp_MakeRequest) | `[ocspMakeRequest](#VB_ocspMakeRequest)` |
| [`OCSP_ReadResponse`](#OCSP_ReadResponse) | [Ocsp.ReadResponse Method](#M_Ocsp_ReadResponse) | `[ocspReadResponse](#VB_ocspReadResponse)` |
| [`PAD_BytesBlock`](#PAD_BytesBlock) | [Cipher.Pad Method](#M_Cipher_Pad_ByteCipherAlgorithmPadding) | `[padBytesBlock](#VB_padBytesBlock)` |
| [`PAD_HexBlock`](#PAD_HexBlock) | [Cipher.Pad Method](#M_Cipher_Pad_StringCipherAlgorithmPadding) (String, CipherAlgorithm, Padding) | `[padHexBlock](#VB_padHexBlock)` |
| [`PAD_UnpadBytes`](#PAD_UnpadBytes) | [Cipher.Unpad Method](#M_Cipher_Unpad_ByteCipherAlgorithmPadding) (Byte[], CipherAlgorithm, Padding) | `[padUnpadBytes](#VB_padUnpadBytes)` |
| [`PAD_UnpadHex`](#PAD_UnpadHex) | [Cipher.Pad Method](#M_Cipher_Unpad_StringCipherAlgorithmPadding) (String, CipherAlgorithm, Padding) | `[padUnpadHex](#VB_padUnpadHex)` |
| [`PBE_Kdf2`](#PBE_Kdf2) | [Pbe.Kdf2 Method](#M_Pbe_Kdf2_Int32ByteByteInt32HashAlgorithm) (Int32, Byte[], Byte[], Int32, HashAlgorithm) | `[pbeKdf2](#VB_pbeKdf2)` |
| [`PBE_Kdf2Hex`](#PBE_Kdf2Hex) | [Pbe.Kdf2 Method](#M_Pbe_Kdf2_Int32StringStringInt32HashAlgorithm) (Int32, String, String, Int32, HashAlgorithm) | `[pbeKdf2Hex](#VB_pbeKdf2Hex)` |
| [`PBE_Scrypt`](#PBE_Scrypt) | [Pbe.Scrypt Method](#M_Pbe_Scrypt_Int32ByteByteInt32Int32Int32) | `[pbeScrypt](#VB_pbeScrypt)` |
| [`PBE_ScryptHex`](#PBE_ScryptHex) | [Pbe.Scrypt Method](#M_Pbe_Scrypt_Int32StringStringInt32Int32Int32) | `[pbeScryptHex](#VB_pbeScryptHex)` |
| [`PEM_FileFromBinFile`](#PEM_FileFromBinFile) [`PEM_FileFromBinFileEx`](#PEM_FileFromBinFileEx) | [Pem.FileFromBinFile Method](#M_Pem_FileFromBinFile) Pem.FileFromBinFile Method |  |
| [`PEM_FileToBinFile`](#PEM_FileToBinFile) | [Pem.FileToBinFile Method](#M_Pem_FileToBinFile) |  |
| [`PFX_MakeFile`](#PFX_MakeFile) | [Pfx.MakeFile Method](#M_Pfx_MakeFile) | `[pfxMakeFile](#VB_pfxMakeFile)` |
| [`PFX_VerifySig`](#PFX_VerifySig) | [Pfx.SignatureIsValid Method](#M_Pfx_SignatureIsValid) |  |
| [`PKI_CompileTime`](#PKI_CompileTime) | [General.CompileTime Method](#M_General_CompileTime) | `[pkiCompileTime](#VB_pkiCompileTime)` |
| [`PKI_ErrorCode`](#PKI_ErrorCode) | [General.ErrorCode Method](#M_General_ErrorCode) | `[pkiErrorCode](#VB_pkiErrorCode)` |
| [`PKI_ErrorLookup`](#PKI_ErrorLookup) | [General.ErrorLookup Method](#M_General_ErrorLookup) | `[pkiErrorLookup](#VB_pkiErrorLookup)` |
| [`PKI_FormatErrorMessage`](#PKI_FormatErrorMessage) | [General.FormatErrorMessage Method](#M_General_FormatErrorMessage) | `[errFormatErrorMessage](#VB_errFormatErrorMessage)` |
| [`PKI_LastError`](#PKI_LastError) | [General.LastError Method](#M_General_LastError) | `[pkiLastError](#VB_pkiLastError)` |
| [`PKI_LicenceType`](#PKI_LicenceType) | [General.LicenceType Method](#M_General_LicenceType) | `[pkiLicenceType](#VB_pkiLicenceType)` |
| [`PKI_ModuleInfo`](#PKI_ModuleInfo) | [General.ModuleInfo Method](#M_General_ModuleInfo) | `[pkiModuleInfo](#VB_pkiModuleInfo)` |
| [`PKI_ModuleName`](#PKI_ModuleName) | [General.ModuleName Method](#M_General_ModuleName) | `[pkiModuleName](#VB_pkiModuleName)` |
| [`PKI_Platform`](#PKI_Platform) | [General.Platform Method](#M_General_Platform) | `[pkiPlatform](#VB_pkiPlatform)` |
| [`PKI_PowerUpTests`](#PKI_PowerUpTests) | [General.PowerUpTests Method](#M_General_PowerUpTests) |  |
| [`PKI_Version`](#PKI_Version) | [General.Version Method](#M_General_Version) | `[pkiVersion](#VB_pkiVersion)` |
| [`PRF_Bytes`](#PRF_Bytes) | [Prf.Bytes Method](#M_Prf_Bytes) | [`prfBytes`](#VB_prfBytes) |
| [`PWD_Prompt`](#PWD_Prompt) [`PWD_PromptEx`](#PWD_PromptEx) | [Pwd.Prompt Method](#M_Pwd_Prompt) | `[pwdPrompt](#VB_pwdPrompt)` |
| [`RNG_Bytes`](#RNG_Bytes) | [Rng.Bytes Method](#M_Rng_Bytes_Int32) (Int32) [Rng.Bytes Method](#M_Rng_Bytes_Int32Byte) (Int32, Byte) [Rng.Bytes Method](#M_Rng_Bytes_Int32String) (Int32, String) | `[rngBytes](#VB_rngBytes)` |
| [`RNG_BytesWithPrompt`](#RNG_BytesWithPrompt) | [Rng.BytesWithPrompt Method](#M_Rng_BytesWithPrompt_Int32Rng_Strength) (Int32, Rng.Strength) [Rng.BytesWithPrompt Method](#M_Rng_BytesWithPrompt_Int32StringRng_Strength) (Int32, String, Rng.Strength) |  |
| [`RNG_Guid`](#RNG_Guid) | [Rng.Guid Method](#M_Rng_Guid) | `[rngGuid](#VB_rngGuid)` |
| [`RNG_Initialize`](#RNG_Initialize) | [Rng.Initialize Method](#M_Rng_Initialize) [Rng.InitializeEx Method](#M_Rng_InitializeEx) | `[rngInitialize](#VB_rngInitialize)` `[rngInitializeEx](#VB_rngInitializeEx)` |
| [`RNG_MakeSeedFile`](#RNG_MakeSeedFile) | [Rng.MakeSeedFile Method](#M_Rng_MakeSeedFile) |  |
| [`RNG_Number`](#RNG_Number) | [Rng.Number Method](#M_Rng_Number) [Rng.Octet Method](#M_Rng_Octet) |  |
| [`RNG_String`](#RNG_String) - @deprecated | Not applicable |  |
| [`RNG_StringWithPrompt`](#RNG_StringWithPrompt) - @deprecated | Not applicable |  |
| [`RNG_Test`](#RNG_Test) | [Rng.Test Method](#M_Rng_Test) |  |
| [`RNG_TestDRBGVS`](#RNG_TestDRBGVS) | [Rng.TestDrbgvs Method](#M_Rng_TestDrbgvs) |  |
| [`RNG_UpdateSeedFile`](#RNG_UpdateSeedFile) | [Rng.UpdateSeedFile Method](#M_Rng_UpdateSeedFile) |  |
| [`RSA_CheckKey`](#RSA_CheckKey) | [Rsa.CheckKey Method](#M_Rsa_CheckKey_String) (String) [Rsa.CheckKey Method](#M_Rsa_CheckKey_StringBuilder) (StringBuilder) |  |
| [`RSA_DecodeMsg`](#RSA_DecodeMsg) | [Rsa.DecodeMsgForEncryption Method](#M_Rsa_DecodeMsgForEncryption) [Rsa.DecodeDigestForSignature Method](#M_Rsa_DecodeDigestForSignature) [Rsa.DecodeMsgIso9796 Method](#M_Rsa_DecodeMsgIso9796) | `[rsaDecodeMsg](#VB_rsaDecodeMsg)` |
| [`RSA_Decrypt`](#RSA_Decrypt) | [Rsa.Decrypt Method](#M_Rsa_Decrypt) | `[rsaDecrypt](#VB_rsaDecrypt)` |
| [`RSA_EncodeMsg`](#RSA_EncodeMsg) | [Rsa.EncodeMsgForEncryption Method](#M_Rsa_EncodeMsgForEncryption) [Rsa.EncodeMsgForSignature Method](#M_Rsa_EncodeMsgForSignature) [Rsa.EncodeDigestForSignature Method](#M_Rsa_EncodeDigestForSignature) [Rsa.EncodeMsgIso9796 Method](#M_Rsa_EncodeMsgIso9796) | `[rsaEncodeMsg](#VB_rsaEncodeMsg)` |
| [`RSA_Encrypt`](#RSA_Encrypt) | [Rsa.Encrypt Method](#M_Rsa_Encrypt) | `[rsaEncrypt](#VB_rsaEncrypt)` |
| [`RSA_FromXMLString`](#RSA_FromXMLString) | [Rsa.FromXMLString Method (String)](#M_Rsa_FromXMLString_String) [Rsa.FromXMLString Method (String, Rsa.XmlOptions)](#M_Rsa_FromXMLString_StringRsa_XmlOptions) [Rsa.FromXMLString Method (String, Boolean)](#M_Rsa_FromXMLString_StringBoolean) | `[rsaFromXMLString](#VB_rsaFromXMLString)` |
| [`RSA_GetPrivateKeyFromPFX`](#RSA_GetPrivateKeyFromPFX) | [Rsa.GetPrivateKeyFromPFX Method](#M_Rsa_GetPrivateKeyFromPFX) |  |
| [`RSA_GetPublicKeyFromCert`](#RSA_GetPublicKeyFromCert) - @deprecated | [Rsa.GetPublicKeyFromCert Method](#M_Rsa_GetPublicKeyFromCert) - @deprecated |  |
| [`RSA_KeyBits`](#RSA_KeyBits) | [Rsa.KeyBits Method](#M_Rsa_KeyBits_String) (String) [Rsa.KeyBits Method](#M_Rsa_KeyBits_StringBuilder) (StringBuilder) | `[rsaKeyBits](#VB_rsaKeyBits)` |
| [`RSA_KeyBytes`](#RSA_KeyBytes) | [Rsa.KeyBytes Method](#M_Rsa_KeyBytes_String) (String) [Rsa.KeyBytes Method](#M_Rsa_KeyBytes_StringBuilder) (StringBuilder) | `[rsaKeyBytes](#VB_rsaKeyBytes)` |
| [`RSA_KeyHashCode`](#RSA_KeyHashCode) | [Rsa.KeyHashCode Method](#M_Rsa_KeyHashCode_String) (String) [Rsa.KeyHashCode Method](#M_Rsa_KeyHashCode_StringBuilder) (StringBuilder) |  |
| [`RSA_KeyMatch`](#RSA_KeyMatch) | [Rsa.KeyMatch Method](#M_Rsa_KeyMatch_StringString) (String) [Rsa.KeyMatch Method](#M_Rsa_KeyMatch_StringBuilderStringBuilder) (StringBuilder) |  |
| [`RSA_KeyValue`](#RSA_KeyValue) | [Rsa.KeyValue Method](#M_Rsa_KeyValue) | `[rsaKeyValue](#VB_rsaKeyValue)` |
| [`RSA_MakeKeys`](#RSA_MakeKeys) - @deprecated | [Rsa.MakeKeys Method](#M_Rsa_MakeKeys_StringStringInt32Rsa_PublicExponentInt32StringRsa_PbeOptionsBooleanByte) (String, String, Int32, Rsa.PublicExponent, Int32, String, Rsa.PbeOptions, Boolean, Byte[]) [Rsa.MakeKeys Method](#M_Rsa_MakeKeys_StringStringInt32Rsa_PublicExponentInt32StringCipherAlgorithmHashAlgorithmRsa_FormatBoolean) (String, String, Int32, Rsa.PublicExponent, Int32, String, CipherAlgorithm, HashAlgorithm, Rsa.Format, Boolean) | `[rsaMakeKeys](#VB_rsaMakeKeys)` |
| [`RSA_MakeKeysXtd`](#RSA_MakeKeysXtd) | [Rsa.MakeKeys Method](#M_Rsa_MakeKeys_StringStringStringInt32Rsa_PublicExponentRsa_PbeOptionsStringRsa_FormatBoolean) (String, String, String, Int32, Rsa.PublicExponent, Rsa.PbeOptions, String, Rsa.Format, Boolean) | `[rsaMakeKeys](#VB_rsaMakeKeys)` |
| [`RSA_PublicKeyFromPrivate`](#RSA_PublicKeyFromPrivate) | [Rsa.PublicKeyFromPrivate Method](#M_Rsa_PublicKeyFromPrivate) | `[rsaPublicKeyFromPrivate](#VB_rsaPublicKeyFromPrivate)` |
| [`RSA_RawPrivate`](#RSA_RawPrivate) | [Rsa.RawPrivate Method](#M_Rsa_RawPrivate_ByteString) (Byte[], String) [Rsa.RawPrivate Method](#M_Rsa_RawPrivate_ByteStringInt32) (Byte[], String, Int32) | `[rsaRawPrivate](#VB_rsaRawPrivate)` |
| [`RSA_RawPublic`](#RSA_RawPublic) | [Rsa.RawPublic Method](#M_Rsa_RawPublic_ByteString) (Byte[], String) [Rsa.RawPublic Method](#M_Rsa_RawPublic_ByteStringInt32) (Byte[], String, Int32) | `[rsaRawPublic](#VB_rsaRawPublic)` |
| [`RSA_ReadAnyPrivateKey`](#RSA_ReadAnyPrivateKey) | [Rsa.ReadPrivateKey Method](#M_Rsa_ReadPrivateKey) | `[rsaReadPrivateKey](#VB_rsaReadPrivateKey)` `[rsaReadAnyPrivateKey](#VB_rsaReadAnyPrivateKey)` |
| [`RSA_ReadAnyPublicKey`](#RSA_ReadAnyPublicKey) | [Rsa.ReadPublicKey Method](#M_Rsa_ReadPublicKey) | `[rsaReadPublicKey](#VB_rsaReadPublicKey)` `[rsaReadAnyPublicKey](#VB_rsaReadAnyPublicKey)` |
| [`RSA_ReadEncPrivateKey`](#RSA_ReadEncPrivateKey) - @deprecated | [Rsa.ReadEncPrivateKey Method](#M_Rsa_ReadEncPrivateKey) - @deprecated |  |
| [`RSA_ReadPrivateKeyFromPFX`](#RSA_ReadPrivateKeyFromPFX) - @deprecated | [Rsa.ReadPrivateKeyFromPFX Method](#M_Rsa_ReadPrivateKeyFromPFX) - @deprecated |  |
| [`RSA_ReadPrivateKeyInfo`](#RSA_ReadPrivateKeyInfo) - @deprecated | [Rsa.ReadPrivateKeyInfo Method](#M_Rsa_ReadPrivateKeyInfo) - @deprecated |  |
| [`RSA_ReadPublicKey`](#RSA_ReadPublicKey) - @deprecated | [Rsa.ReadPublicKey Method](#M_Rsa_ReadPublicKey) | `[rsaReadPublicKey](#VB_rsaReadPublicKey)` |
| [`RSA_SaveEncKey`](#RSA_SaveEncKey) | [Rsa.SaveEncKey Method](#M_Rsa_SaveEncKey) | `[rsaSaveEncKey](#VB_rsaSaveEncKey)` |
| [`RSA_SaveEncPrivateKey`](#RSA_SaveEncPrivateKey) | [Rsa.SaveEncPrivateKey Method](#M_Rsa_SaveEncPrivateKey_StringStringInt32StringRsa_PbeOptionsRsa_Format) (String, String, Int32, String, Rsa.PbeOptions, Rsa.Format) [Rsa.SaveEncPrivateKey Method](#M_Rsa_SaveEncPrivateKey_StringStringInt32StringCipherAlgorithmHashAlgorithmRsa_Format) (String, String, Int32, String, CipherAlgorithm, HashAlgorithm, Rsa.Format) | `[rsaSaveEncKey](#VB_rsaSaveEncKey)` |
| [`RSA_SavePrivateKeyInfo`](#RSA_SavePrivateKeyInfo) | [Rsa.SavePrivateKeyInfo Method](#M_Rsa_SavePrivateKeyInfo) | `[rsaSaveKey](#VB_rsaSaveKey)` |
| [`RSA_SavePublicKey`](#RSA_SavePublicKey) | [Rsa.SavePublicKey Method](#M_Rsa_SavePublicKey) | `[rsaSaveKey](#VB_rsaSaveKey)` |
| [`RSA_ToXMLString`](#RSA_ToXMLString) | [Rsa.ToXMLString Method (String, Rsa.XmlOptions)](#M_Rsa_ToXMLString_StringRsa_XmlOptions) | `[rsaToXMLString](#VB_rsaToXMLString)` |
| [`RSA_ToXMLStringEx`](#RSA_ToXMLStringEx) | [Rsa.ToXMLString Method (String, String, Rsa.XmlOptions)](#M_Rsa_ToXMLString_StringStringRsa_XmlOptions) | `[rsaToXMLStringEx](#VB_rsaToXMLStringEx)` |
| [`SIG_SignData`](#SIG_SignData) | [Sig.SignData Method](#M_Sig_SignData) [Sig.SignDigest Method](#M_Sig_SignDigest) | `[sigSignData](#VB_sigSignData)` |
| [`SIG_SignFile`](#SIG_SignFile) | [Sig.SignFile Method](#M_Sig_SignFile) | `[sigSignFile](#VB_sigSignFile)` |
| [`SIG_VerifyData`](#SIG_VerifyData) | [Sig.VerifyData Method](#M_Sig_VerifyData) [Sig.VerifyDigest Method](#M_Sig_VerifyDigest) | `[sigVerifyData](#VB_sigVerifyData)` |
| [`SIG_VerifyFile`](#SIG_VerifyFile) | [Sig.VerifyFile Method](#M_Sig_VerifyFile) (String, String, String, SigAlgorithm, Sig.VerifyOpts) |  |
| [`SMIME_Extract`](#SMIME_Extract) | [Smime.Extract Method](#M_Smime_Extract) |  |
| [`SMIME_Query`](#SMIME_Query) | [Smime.Query Method](#M_Smime_Query) | `[smimeQuery](#VB_smimeQuery)` |
| [`SMIME_Wrap`](#SMIME_Wrap) | [Smime.Wrap Method](#M_Smime_Wrap) |  |
| [`TDEA_B64Mode`](#TDEA_B64Mode) | [Tdea.Encrypt Method](#M_Tdea_Encrypt_StringStringModeStringEncodingBase) (String, String, Mode, String, EncodingBase) [Tdea.Decrypt Method](#M_Tdea_Decrypt_StringStringModeStringEncodingBase) (String, String, Mode, String, EncodingBase) |  |
| [`TDEA_BytesMode`](#TDEA_BytesMode) | [Tdea.Encrypt Method](#M_Tdea_Encrypt_ByteByteModeByte) (Byte[], Byte[], Mode, Byte[]) [Tdea.Decrypt Method](#M_Tdea_Decrypt_ByteByteModeByte) (Byte[], Byte[], Mode, Byte[]) |  |
| [`TDEA_File`](#TDEA_File) | [Tdea.FileEncrypt Method](#M_Tdea_FileEncrypt_StringStringByteModeByte) (String, String, Byte[], Mode, Byte[]) [Tdea.FileDecrypt Method](#M_Tdea_FileDecrypt_StringStringByteModeByte) (String, String, Byte[], Mode, Byte[]) |  |
| [`TDEA_HexMode`](#TDEA_HexMode) | [Tdea.Encrypt Method](#M_Tdea_Encrypt_StringStringModeString) (String, String, Mode, String) [Tdea.Decrypt Method](#M_Tdea_Decrypt_StringStringModeString) (String, String, Mode, String) |  |
| [`WIPE_Data`](#WIPE_Data) | [Wipe.Data Method](#M_Wipe_Data) [Wipe.String Method](#M_Wipe_String) | `[wipeBytes](#VB_wipeBytes)` `[wipeString](#VB_wipeString)` |
| [`WIPE_File`](#WIPE_File) | [Wipe.File Method](#M_Wipe_File) |  |
| [`X509_CertExpiresOn`](#X509_CertExpiresOn) | [X509.CertExpiresOn Method](#M_X509_CertExpiresOn) |  |
| [`X509_CertIssuedOn`](#X509_CertIssuedOn) | [X509.CertIssuedOn Method](#M_X509_CertIssuedOn) |  |
| [`X509_CertIssuerName`](#X509_CertIssuerName) | [X509.CertIssuerName Method](#M_X509_CertIssuerName) |  |
| [`X509_CertIsValidNow`](#X509_CertIsValidNow) | [X509.CertIsValidNow Method](#M_X509_CertIsValidNow) |  |
| [`X509_CertRequest`](#X509_CertRequest) | [X509.CertRequest Method](#M_X509_CertRequest) |  |
| [`X509_CertSerialNumber`](#X509_CertSerialNumber) | [X509.CertSerialNumber Method](#M_X509_CertSerialNumber) |  |
| [`X509_CertSubjectName`](#X509_CertSubjectName) | [X509.CertSubjectName Method](#M_X509_CertSubjectName) |  |
| [`X509_CertThumb`](#X509_CertThumb) | [X509.CertThumb Method](#M_X509_CertThumb) | `[x509CertThumb](#VB_x509CertThumb)` |
| [`X509_CheckCertInCRL`](#X509_CheckCertInCRL) | [X509.CheckCertInCRL Method](#M_X509_CheckCertInCRL) |  |
| [`X509_GetCertCountInP7Chain`](#X509_GetCertCountInP7Chain) | [X509.GetCertCountInP7Chain Method](#M_X509_GetCertCountInP7Chain) |  |
| [`X509_GetCertFromP7Chain`](#X509_GetCertFromP7Chain) | [X509.GetCertFromP7Chain Method](#M_X509_GetCertFromP7Chain) |  |
| [`X509_GetCertFromPFX`](#X509_GetCertFromPFX) | [X509.GetCertFromPFX Method](#M_X509_GetCertFromPFX) [X509.GetP7ChainFromPFX Method](#M_X509_GetP7ChainFromPFX) |  |
| [`X509_HashIssuerAndSN`](#X509_HashIssuerAndSN) | [X509.HashIssuerAndSN Method](#M_X509_HashIssuerAndSN) | `[x509HashIssuerAndSN](#VB_x509HashIssuerAndSN)` |
| [`X509_KeyUsageFlags`](#X509_KeyUsageFlags) | [X509.KeyUsageFlags Method](#M_X509_KeyUsageFlags) |  |
| [`X509_MakeCert`](#X509_MakeCert) | [X509.MakeCert Method](#M_X509_MakeCert) |  |
| [`X509_MakeCertSelf`](#X509_MakeCertSelf) | [X509.MakeCertSelf Method](#M_X509_MakeCertSelf) |  |
| [`X509_MakeCRL`](#X509_MakeCRL) | [X509.MakeCRL Method](#M_X509_MakeCRL) |  |
| [`X509_QueryCert`](#X509_QueryCert) | [X509.QueryCert Method](#M_X509_QueryCert) | `[x509QueryCert](#VB_x509QueryCert)` |
| [`X509_ReadCertStringFromP7Chain`](#X509_ReadCertStringFromP7Chain) | [X509.ReadCertStringFromP7Chain Method](#M_X509_ReadCertStringFromP7Chain) | `[x509ReadCertStringFromP7Chain](#VB_x509ReadCertStringFromP7Chain)` |
| [`X509_ReadCertStringFromPFX`](#X509_ReadCertStringFromPFX) | [X509.ReadCertStringFromPFX Method](#M_X509_ReadCertStringFromPFX) | `[x509ReadCertStringFromPFX](#VB_x509ReadCertStringFromPFX)` |
| [`X509_ReadStringFromFile`](#X509_ReadStringFromFile) | [X509.ReadStringFromFile Method](#M_X509_ReadStringFromFile) | `[x509ReadStringFromFile](#VB_x509ReadStringFromFile)` |
| [`X509_SaveFileFromString`](#X509_SaveFileFromString) | [X509.SaveFileFromString Method](#M_X509_SaveFileFromString) |  |
| [`X509_TextDump`](#X509_TextDump) | [X509.TextDump Method](#M_X509_TextDump) |  |
| [`X509_TextDumpToString`](#X509_TextDumpToString) | [X509.TextDumpToString Method](#M_X509_TextDumpToString) | `[x509TextDumpToString](#VB_x509TextDumpToString)` |
| [`X509_ValidatePath`](#X509_ValidatePath) | [X509.ValidatePath Method](#M_X509_ValidatePath) |  |
| [`X509_VerifyCert`](#X509_VerifyCert) | [X509.VerifyCert Method](#M_X509_VerifyCert) |  |
| [`XOF_Bytes`](#XOF_Bytes) | [Xof.Bytes Method](#M_Xof_Bytes) | [`xofBytes`](#VB_xofBytes) |

[[Contents](#topofpage)] [[Index](#index)]

### <a id="dotnethelp"></a>.NET Help File

The .NET classes and methods have different parameters and return values to the VB6/C functions
described above. 

Full details are provided in [Summary of .NET Classes](#dotnetsummary) below
and also in the help file `CryptoSysPKI.NET.chm` available separately.

[[Contents](#topofpage)] [[Index](#index)]

<a id="dotnetsummary"></a>Summary of .NET Classes
-------------------------------------------------

This manual includes the complete information from the .NET Help File plus cross-references to the equivalent
VB6/C functions and examples in `VB.NET`.
For a summary showing the VB6/C equivalent functions for these .NET methods, see 
[Cross-reference between Functions and .NET Methods](#xrefdotnet).

---

Class index:   
[Asn1](#mx_Asn1) |
[Cipher](#mx_Cipher) |
[Cms](#mx_Cms) |
[Cnv](#mx_Cnv) |
[Compr](#mx_Compr) |
[Ecc](#mx_Ecc) |
[General](#mx_General) |
[Hash](#mx_Hash) |
[Hmac](#mx_Hmac) |
[Hpke](#mx_Hpke) |
[Kdf](#mx_Kdf) |
[Ocsp](#mx_Ocsp) |
[Pbe](#mx_Pbe) |
[Pem](#mx_Pem) |
[Pfx](#mx_Pfx) |
[Prf](#mx_Prf) |
[Pwd](#mx_Pwd) |
[Rng](#mx_Rng) |
[Rsa](#mx_Rsa) |
[Sig](#mx_Sig) |
[Smime](#mx_Smime) |
[Tdea](#mx_Tdea) |
[Wipe](#mx_Wipe) |
[X509](#mx_X509) |
[Xof](#mx_Xof)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="mx_Asn1"></a>Asn1 Class

* [Asn1.TextDump Method](#M_Asn1_TextDump)

    + Dump details of an ASN.1 formatted data file to a text file.
* [Asn1.TextDumpToString Method](#M_Asn1_TextDumpToString)

    + Dump details of ASN.1 formatted data to a string.
* [Asn1.Type Method](#M_Asn1_Type)

    + Describe the type of ASN.1 data.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Cipher"></a>Cipher Class

* [Cipher.BlockBytes Method](#M_Cipher_BlockBytes)

    + Return the block size in bytes for a given cipher algorithm.
* [Cipher.Decrypt Method ](#M_Cipher_Decrypt_ByteByteByteCipherAlgorithmMode) (Byte[], Byte[], Byte[], CipherAlgorithm, Mode)

    + Decrypt data block in byte array.
* [Cipher.Decrypt Method ](#M_Cipher_Decrypt_ByteByteByteCipherAlgorithmModePaddingCipher_Opts) (Byte[], Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)

    + Decrypt data in a byte array using the specified block cipher algorithm, mode and padding.
* [Cipher.Decrypt Method ](#M_Cipher_Decrypt_StringStringStringCipherAlgorithmMode) (String, String, String, CipherAlgorithm, Mode)

    + Decrypt data block as hex-encoded string.
* [Cipher.Decrypt Method ](#M_Cipher_Decrypt_StringStringStringCipherAlgorithmModePaddingCipher_Opts) (String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts)

    + Decrypt hex-encoded data using specified block cipher algorithm, mode and padding.
* [Cipher.DecryptAEAD Method ](#M_Cipher_DecryptAEAD_ByteByteByteAeadAlgorithm) (Byte[], Byte[], Byte[], AeadAlgorithm)

    + Decrypt data using the AES-GCM authenticated encryption algorithm.
* [Cipher.DecryptAEAD Method ](#M_Cipher_DecryptAEAD_ByteByteByteByteAeadAlgorithmCipher_Opts) (Byte[], Byte[], Byte[], Byte[], AeadAlgorithm, Cipher.Opts)

    + Decrypt data using the AES-GCM authenticated encryption algorithm with AAD and options.
* [Cipher.Encrypt Method ](#M_Cipher_Encrypt_ByteByteByteCipherAlgorithmMode) (Byte[], Byte[], Byte[], CipherAlgorithm, Mode)

    + Encrypt data block in byte array.
* [Cipher.Encrypt Method ](#M_Cipher_Encrypt_ByteByteByteCipherAlgorithmModePaddingCipher_Opts) (Byte[], Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)

    + Encrypt data in a byte array using the specified block cipher algorithm, mode and padding.
* [Cipher.Encrypt Method ](#M_Cipher_Encrypt_StringStringStringCipherAlgorithmMode) (String, String, String, CipherAlgorithm, Mode)

    + Encrypt data block as hex-encoded string.
* [Cipher.Encrypt Method ](#M_Cipher_Encrypt_StringStringStringCipherAlgorithmModePaddingCipher_Opts) (String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts)

    + Encrypt hex-encoded data using specified block cipher algorithm, mode and padding.
* [Cipher.EncryptAEAD Method ](#M_Cipher_EncryptAEAD_ByteByteByteAeadAlgorithm) (Byte[], Byte[], Byte[], AeadAlgorithm)

    + Encrypt data using the AES-GCM authenticated encryption algorithm.
* [Cipher.EncryptAEAD Method ](#M_Cipher_EncryptAEAD_ByteByteByteByteAeadAlgorithmCipher_Opts) (Byte[], Byte[], Byte[], Byte[], AeadAlgorithm, Cipher.Opts)

    + Encrypt data using the AES-GCM authenticated encryption algorithm with AAD and options.
* [Cipher.FileDecrypt Method ](#M_Cipher_FileDecrypt_StringStringByteByteCipherAlgorithmModePaddingCipher_Opts) (String, String, Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)

    + Decrypt a file.
* [Cipher.FileDecrypt Method ](#M_Cipher_FileDecrypt_StringStringStringStringCipherAlgorithmModePaddingCipher_Opts) (String, String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts)

    + Decrypt a file passing key and IV as hex strings.
* [Cipher.FileEncrypt Method ](#M_Cipher_FileEncrypt_StringStringByteByteCipherAlgorithmModePaddingCipher_Opts) (String, String, Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)

    + Encrypt a file.
* [Cipher.FileEncrypt Method ](#M_Cipher_FileEncrypt_StringStringStringStringCipherAlgorithmModePaddingCipher_Opts) (String, String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts)

    + Encrypt a file passing key and IV as hex strings.
* [Cipher.KeyBytes Method](#M_Cipher_KeyBytes)

    + Return the key size in bytes for a given cipher algorithm.
* [Cipher.KeyUnwrap Method](#M_Cipher_KeyUnwrap)

    + Unwrap (decrypt) key material with a key-encryption key.
* [Cipher.KeyWrap Method](#M_Cipher_KeyWrap)

    + Wrap (encrypt) key material with a key-encryption key.
* [Cipher.Pad Method ](#M_Cipher_Pad_ByteCipherAlgorithmPadding) (Byte[], CipherAlgorithm, Padding)

    + Pad byte array to correct length for ECB and CBC encryption.
* [Cipher.Pad Method ](#M_Cipher_Pad_StringCipherAlgorithmPadding) (String, CipherAlgorithm, Padding)

    + Pad hex-encoded string to correct length for ECB and CBC encryption.
* [Cipher.Unpad Method ](#M_Cipher_Unpad_ByteCipherAlgorithmPadding) (Byte[], CipherAlgorithm, Padding)

    + Remove padding from an encryption block.
* [Cipher.Unpad Method ](#M_Cipher_Unpad_StringCipherAlgorithmPadding) (String, CipherAlgorithm, Padding)

    + Remove padding from a hex-encoded encryption block.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Cms"></a>Cms Class

* [Cms.GetSigDataDigest Method](#M_Cms_GetSigDataDigest)

    + Extract the message digest from a signed-data CMS object file and verify the signature.
* [Cms.GetSigHashAlgorithm Method](#M_Cms_GetSigHashAlgorithm)

    + Find ID of message digest hash algorithm used to make signature.
* [Cms.MakeComprData Method](#M_Cms_MakeComprData)

    + Create a new CMS compressed-data file (.p7z) from an existing input file.
* [Cms.MakeDetachedSig Method](#M_Cms_MakeDetachedSig)

    + Create a "detached signature" CMS signed-data object file from a **message digest** of the content (advanced algorithms).
* [Cms.MakeEnvData Method ](#M_Cms_MakeEnvData_StringStringStringCipherAlgorithmCms_EnvDataOptions) (String, String, String, CipherAlgorithm, Cms.EnvDataOptions)

    + Create a CMS enveloped-data object (default recipient parameters).
* [Cms.MakeEnvData Method ](#M_Cms_MakeEnvData_StringStringStringCipherAlgorithmCms_KeyEncrAlgorithmHashAlgorithmCms_EnvDataOptionsKdf_KdfAlgKdf_KeyWrapAlgStringInt32Cms_ContentEncrAlg) (String, String, String, CipherAlgorithm, Cms.KeyEncrAlgorithm, HashAlgorithm, Cms.EnvDataOptions, Kdf.KdfAlg, Kdf.KeyWrapAlg, String, Int32, Cms.ContentEncrAlg)

    + Create a CMS enveloped-data object (advanced options).
* [Cms.MakeEnvDataFromBytes Method](#M_Cms_MakeEnvDataFromBytes)

    + Create a CMS enveloped-data object from data in a byte array.
* [Cms.MakeEnvDataFromString Method ](#M_Cms_MakeEnvDataFromString_StringStringStringCipherAlgorithmCms_EnvDataOptions) (String, String, String, CipherAlgorithm, Cms.EnvDataOptions)

    + Create a CMS enveloped-data object from an ASCII string (default recipient parameters).
* [Cms.MakeEnvDataFromString Method ](#M_Cms_MakeEnvDataFromString_StringStringStringCipherAlgorithmCms_KeyEncrAlgorithmHashAlgorithmCms_EnvDataOptionsKdf_KdfAlgKdf_KeyWrapAlgStringInt32Cms_ContentEncrAlg) (String, String, String, CipherAlgorithm, Cms.KeyEncrAlgorithm, HashAlgorithm, Cms.EnvDataOptions, Kdf.KdfAlg, Kdf.KeyWrapAlg, String, Int32, Cms.ContentEncrAlg)

    + Create a CMS enveloped-data object from an ASCII string (advanced options).
* [Cms.MakeSigData Method ](#M_Cms_MakeSigData_StringStringStringStringCms_SigAlgCms_SigDataOptions) (String, String, String, String, Cms.SigAlg, Cms.SigDataOptions)

    + Create a CMS object of type SignedData from an input data file (advanced options including RSA-PSS).
* [Cms.MakeSigData Method ](#M_Cms_MakeSigData_StringStringStringStringHashAlgorithmCms_SigDataOptions) (String, String, String, String, HashAlgorithm, Cms.SigDataOptions)

    + Create a CMS object of type SignedData from an input data file using RSASSA-PKCS1V1_5 with options.
* [Cms.MakeSigDataFromBytes Method](#M_Cms_MakeSigDataFromBytes)

    + Create a CMS object of type SignedData from an array of bytes.
* [Cms.MakeSigDataFromPseudo Method](#M_Cms_MakeSigDataFromPseudo)

    + Create a SignedData object from a "pseudo" object.
* [Cms.MakeSigDataFromSigValue Method](#M_Cms_MakeSigDataFromSigValue)

    + Create a CMS object of type SignedData using a pre-computed signature (advanced algorithms).
* [Cms.MakeSigDataFromString Method ](#M_Cms_MakeSigDataFromString_StringStringStringStringCms_SigAlgCms_SigDataOptions) (String, String, String, String, Cms.SigAlg, Cms.SigDataOptions)

    + Create a CMS object of type SignedData from an input string (advanced options including RSA-PSS).
* [Cms.MakeSigDataFromString Method ](#M_Cms_MakeSigDataFromString_StringStringStringStringHashAlgorithmCms_SigDataOptions) (String, String, String, String, HashAlgorithm, Cms.SigDataOptions)

    + Create a CMS object of type SignedData from an input string using RSASSA-PKCS1V1_5 with options.
* [Cms.QueryEnvData Method](#M_Cms_QueryEnvData)

    + Query a CMS enveloped-data object file for selected information.
* [Cms.QuerySigData Method](#M_Cms_QuerySigData)

    + Query a CMS signed-data object for selected information.
* [Cms.ReadComprData Method](#M_Cms_ReadComprData)

    + Read and extract the decompressed contents of a CMS compressed-data file.
* [Cms.ReadEnvDataToBytes Method](#M_Cms_ReadEnvDataToBytes)

    + Read and decrypt a CMS enveloped-data object to a byte array.
* [Cms.ReadEnvDataToFile Method](#M_Cms_ReadEnvDataToFile)

    + Read and decrypt a CMS enveloped-data object to a file.
* [Cms.ReadEnvDataToString Method](#M_Cms_ReadEnvDataToString)

    + Read and decrypt a CMS enveloped-data object to a string.
* [Cms.ReadSigDataToBytes Method](#M_Cms_ReadSigDataToBytes)

    + Read the content from a CMS signed-data object directly into a byte array.
* [Cms.ReadSigDataToFile Method](#M_Cms_ReadSigDataToFile)

    + Read the content from a CMS signed-data object file.
* [Cms.ReadSigDataToString Method](#M_Cms_ReadSigDataToString)

    + Read the content from a CMS signed-data object directly into a string.
* [Cms.VerifySigData Method](#M_Cms_VerifySigData)

    + Verify the signature and content of a signed-data CMS object file.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Cnv"></a>Cnv Class

* [Cnv.Base64Filter Method](#M_Cnv_Base64Filter)

    + Filter non-base64 characters from a string.
* [Cnv.Base64FromHex Method](#M_Cnv_Base64FromHex)

    + Convert hexadecimal-encoded data into base64-encoded data.
* [Cnv.ByteEncoding Method](#M_Cnv_ByteEncoding)

    + Convert encoding of byte array between UTF-8 and Latin-1.
* [Cnv.CheckUTF8 Method](#M_Cnv_CheckUTF8)

    + Check that a byte array contains only valid UTF-8 encoded characters.
* [Cnv.CheckUTF8File Method](#M_Cnv_CheckUTF8File)

    + Check that a file contains only valid UTF-8 encoded characters.
* [Cnv.FromBase58 Method](#M_Cnv_FromBase58)

    + Convert a base58-encoded string to an equivalent array of 8-bit unsigned integers.
* [Cnv.FromBase64 Method](#M_Cnv_FromBase64)

    + Convert a base64-encoded string to an equivalent array of 8-bit unsigned integers.
* [Cnv.FromHex Method](#M_Cnv_FromHex)

    + Convert the specified string representation of a value consisting of hexadecimal (base 16) digits to an equivalent array of 8-bit unsigned integers.
* [Cnv.HexFilter Method](#M_Cnv_HexFilter)

    + Filter non-hexadecimal characters from a string.
* [Cnv.HexFromBase64 Method](#M_Cnv_HexFromBase64)

    + Convert base64-encoded data into hexadecimal-encoded data.
* [Cnv.NumFromBytes Method](#M_Cnv_NumFromBytes)

    + Convert the leftmost four bytes of an array to an unsigned 32-bit integer.
* [Cnv.NumToBytes Method](#M_Cnv_NumToBytes)

    + Convert a 32-bit integer to an array of 4 bytes.
* [Cnv.ReverseBytes Method](#M_Cnv_ReverseBytes)

    + Reverse the order of a byte array.
* [Cnv.ShortPathName Method](#M_Cnv_ShortPathName)

    + Retrieve the Windows short path form of the specified path.
* [Cnv.StringFromBase64 Method](#M_Cnv_StringFromBase64)

    + Convert a base64-encoded string into a text string.
* [Cnv.StringFromHex Method](#M_Cnv_StringFromHex)

    + Convert a hexadecimal-encoded string into a text string.
* [Cnv.ToBase58 Method](#M_Cnv_ToBase58)

    + Convert 8-bit binary data to equivalent base58-encoded string format.
* [Cnv.ToBase64 Method ](#M_Cnv_ToBase64_Byte) (Byte[])

    + Convert 8-bit binary data to equivalent base64-encoded string format.
* [Cnv.ToBase64 Method ](#M_Cnv_ToBase64_String) (String)

    + Convert a string of ANSI characters to equivalent base64-encoded string format.
* [Cnv.ToHex Method ](#M_Cnv_ToHex_Byte) (Byte[])

    + Convert 8-bit binary data to equivalent hexadecimal string format.
* [Cnv.ToHex Method ](#M_Cnv_ToHex_String) (String)

    + Converts a string of ANSI characters to equivalent hexadecimal string format

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Compr"></a>Compr Class

* [Compr.Compress Method](#M_Compr_Compress)

    + Compress data using zlib compression.
* [Compr.Uncompress Method](#M_Compr_Uncompress)

    + Uncompress data using zlib compression.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Ecc"></a>Ecc Class

* [Ecc.DHSharedSecret Method](#M_Ecc_DHSharedSecret)

    + Compute EC Diffie-Hellman (ECDH) shared secret.
* [Ecc.KeyHashCode Method](#M_Ecc_KeyHashCode)

    + Compute the hash code of an "internal" ECC public or private key string.
* [Ecc.MakeKeys Method](#M_Ecc_MakeKeys)

    + Generate an EC public/private key pair and save as two key files.
* [Ecc.PublicKeyFromPrivate Method](#M_Ecc_PublicKeyFromPrivate)

    + Convert an internal EC private key string into an internal EC public key string.
* [Ecc.QueryKey Method](#M_Ecc_QueryKey)

    + Query an EC key string for selected information.
* [Ecc.ReadKeyByCurve Method](#M_Ecc_ReadKeyByCurve)

    + Read an EC key from its hexadecimal representation with options for safe curves.
* [Ecc.ReadPrivateKey Method](#M_Ecc_ReadPrivateKey)

    + Read from a file or string containing an EC private key into an "internal" private key string.
* [Ecc.ReadPublicKey Method](#M_Ecc_ReadPublicKey)

    + Read from a file or string containing an EC public key into an "internal" public key string.
* [Ecc.SaveEncKey Method](#M_Ecc_SaveEncKey)

    + Save an internal EC private key string to an encrypted private key file.
* [Ecc.SaveKey Method](#M_Ecc_SaveKey)

    + Save an internal EC key string (public or private) to an unencrypted key file.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_General"></a>General Class

* [General.CompileTime Method](#M_General_CompileTime)

    + Return date and time the core CryptoSys PKI DLL was last compiled.
* [General.ErrorCode Method](#M_General_ErrorCode)

    + Return the error code of the *first* error that occurred when calling the last function.
* [General.ErrorLookup Method](#M_General_ErrorLookup)

    + Return a description of an error code.
* [General.FormatErrorMessage Method](#M_General_FormatErrorMessage)

    + Return an error message string for the last error.
* [General.LastError Method](#M_General_LastError)

    + Retrieve the last error message set by the toolkit.
* [General.LicenceType Method](#M_General_LicenceType)

    + Return licence type.
* [General.ModuleInfo Method](#M_General_ModuleInfo)

    + Get additional information about the core DLL module.
* [General.ModuleName Method](#M_General_ModuleName)

    + Return full path name of core CryptoSys PKI DLL module.
* [General.NetVersion Method](#M_General_NetVersion)

    + Return the version of this .NET module.
* [General.Platform Method](#M_General_Platform)

    + Return the platform the core DLL was compiled for.
* [General.PowerUpTests Method](#M_General_PowerUpTests)

    + Perform FIPS-140-2 start-up tests.
* [General.Version Method](#M_General_Version)

    + Return the release version of the core CryptoSys PKI DLL as an integer value.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Hash"></a>Hash Class

* [Hash.BytesFromBytes Method](#M_Hash_BytesFromBytes)

    + Create hash digest in byte format of byte input.
* [Hash.BytesFromFile Method](#M_Hash_BytesFromFile)

    + Create hash digest of a binary file.
* [Hash.Double Method](#M_Hash_Double)

    + Create double hash, i.e. hash of hash, in byte format of byte input.
* [Hash.HexFromBytes Method](#M_Hash_HexFromBytes)

    + Create hash digest in hex format of byte input.
* [Hash.HexFromFile Method](#M_Hash_HexFromFile)

    + Create hash digest in hex format of a binary file.
* [Hash.HexFromHex Method](#M_Hash_HexFromHex)

    + Create hash digest in hex format of hex-encoded input.
* [Hash.HexFromString Method](#M_Hash_HexFromString)

    + Create hash digest in hex format of string input.
* [Hash.HexFromTextFile Method](#M_Hash_HexFromTextFile)

    + Create hash digest in hex format of a text file, treating CR-LF (0x13, 0x10) pairs as a single LF (0x10).
* [Hash.Length Method](#M_Hash_Length)

    + Return length of message digest output in bytes.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Hmac"></a>Hmac Class

* [Hmac.BytesFromBytes Method](#M_Hmac_BytesFromBytes)

    + Create a keyed-hash HMAC in byte format from byte input.
* [Hmac.HexFromBytes Method](#M_Hmac_HexFromBytes)

    + Create a keyed-hash HMAC in hex-encoded format from byte input.
* [Hmac.HexFromHex Method](#M_Hmac_HexFromHex)

    + Create a keyed-hash HMAC in hex-encoded format from hex-encoded input.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Hpke"></a>Hpke Class

* [Hpke.DerivePrivateKey Method](#M_Hpke_DerivePrivateKey)

    + Derive an EC private key in a deterministic manner from input keying material using the DeriveKeyPair algorithm in RFC9180.
* [Hpke.LabeledExpand Method](#M_Hpke_LabeledExpand)

    + Compute the output of the LabeledExpand function as defined in RFC9180.
* [Hpke.LabeledExtract Method](#M_Hpke_LabeledExtract)

    + Compute the output of the LabeledExtract function as defined in RFC9180.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Kdf"></a>Kdf Class

* [Kdf.Bytes Method](#M_Kdf_Bytes)

    + Generate a key-encryption key (KEK) from input keying material (IKM) using a key derivation function (KDF).
* [Kdf.ForCms Method](#M_Kdf_ForCms)

    + Generate a key-encryption key (KEK) for ECDH key exchange in a CMS EnvelopedData object.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Ocsp"></a>Ocsp Class

* [Ocsp.MakeRequest Method](#M_Ocsp_MakeRequest)

    + Create an Online Certification Status Protocol (OCSP) request as a base64 string.
* [Ocsp.ReadResponse Method](#M_Ocsp_ReadResponse)

    + Read a response to an Online Certification Status Protocol (OCSP) request and outputs the main results in text form.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Pbe"></a>Pbe Class

* [Pbe.Kdf2 Method ](#M_Pbe_Kdf2_Int32ByteByteInt32HashAlgorithm) (Int32, Byte[], Byte[], Int32, HashAlgorithm)

    + Derive a key of any length from a password using the PBKDF2 algorithm from PKCS #5 v2.1.
* [Pbe.Kdf2 Method ](#M_Pbe_Kdf2_Int32StringStringInt32HashAlgorithm) (Int32, String, String, Int32, HashAlgorithm)

    + Derive a key in hex format of any length from a password with the salt in hex format.
* [Pbe.Scrypt Method ](#M_Pbe_Scrypt_Int32ByteByteInt32Int32Int32) (Int32, Byte[], Byte[], Int32, Int32, Int32)

    + Derives a key of any length from a password using the SCRYPT algorithm.
* [Pbe.Scrypt Method ](#M_Pbe_Scrypt_Int32StringStringInt32Int32Int32) (Int32, String, String, Int32, Int32, Int32)

    + Derives a key in hex format from a password with the salt in hex format

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Pem"></a>Pem Class

* [Pem.FileFromBinFile Method](#M_Pem_FileFromBinFile)

    + Create a PEM file from a binary file with option for line endings.
* [Pem.FileToBinFile Method](#M_Pem_FileToBinFile)

    + Convert the contents of a PEM file into a binary file.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Pfx"></a>Pfx Class

* [Pfx.MakeFile Method](#M_Pfx_MakeFile)

    + Create a PFX (PKCS-12) file from an X.509 certificate and (optional) encrypted private key file with advanced options.
* [Pfx.SignatureIsValid Method](#M_Pfx_SignatureIsValid)

    + Verify the MacData signature in a PKCS-12 file.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Prf"></a>Prf Class

* [Prf.Bytes Method](#M_Prf_Bytes)

    + Generate output bytes using a pseudorandom function (PRF).

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Pwd"></a>Pwd Class

* [Pwd.Prompt Method](#M_Pwd_Prompt)

    + Open a dialog box to receive a password with user-supplied prompt.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Rng"></a>Rng Class

* [Rng.Bytes Method ](#M_Rng_Bytes_Int32) (Int32)

    + Generate an array of random bytes.
* [Rng.Bytes Method ](#M_Rng_Bytes_Int32Byte) (Int32, Byte[])

    + Generate an array of random bytes with user-supplied entropy.
* [Rng.Bytes Method ](#M_Rng_Bytes_Int32String) (Int32, String)

    + Generate an array of random bytes with user-supplied entropy.
* [Rng.BytesWithPrompt Method ](#M_Rng_BytesWithPrompt_Int32Rng_Strength) (Int32, Rng.Strength)

    + Generate an array of random bytes with a prompt for random keyboard input.
* [Rng.BytesWithPrompt Method ](#M_Rng_BytesWithPrompt_Int32StringRng_Strength) (Int32, String, Rng.Strength)

    + Generate an array of random bytes with a prompt for random keyboard input.
* [Rng.Guid Method](#M_Rng_Guid)

    + Generate a random 36-character Global Unique IDentifier (GUID) string according to [RFC4122].
* [Rng.Initialize Method](#M_Rng_Initialize)

    + Initialize the RNG generator with a seed file.
* [Rng.InitializeEx Method](#M_Rng_InitializeEx)

    + Query and initialize the RNG generator using Intel(R) DRNG, if available.
* [Rng.MakeSeedFile Method](#M_Rng_MakeSeedFile)

    + Create a new seed file suitable for use with Rng.Initialize.
* [Rng.Number Method](#M_Rng_Number)

    + Generate a random number (integer) in a given range.
* [Rng.Octet Method](#M_Rng_Octet)

    + Generate a single random octet (byte).
* [Rng.Test Method](#M_Rng_Test)

    + Carry out a NIST SP800-90 health check and FIPS140-2 statistical tests on the random number generator.
* [Rng.TestDrbgvs Method](#M_Rng_TestDrbgvs)

    + Test the RNG for conformance to NIST SP800-90A using the relevant test specified in DRBGVS.
* [Rng.UpdateSeedFile Method](#M_Rng_UpdateSeedFile)

    + Update the RNG seed file.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Rsa"></a>Rsa Class

* [Rsa.CheckKey Method ](#M_Rsa_CheckKey_String) (String)

    + Check the validity of an "internal" RSA public or private key.
* [Rsa.CheckKey Method ](#M_Rsa_CheckKey_StringBuilder) (StringBuilder)

    + Check the validity of an "internal" RSA public or private key.
* [Rsa.DecodeDigestForSignature Method](#M_Rsa_DecodeDigestForSignature)

    + Decode an encoded message for signature.
* [Rsa.DecodeMsgForEncryption Method](#M_Rsa_DecodeMsgForEncryption)

    + Decode a message for encryption.
* [Rsa.DecodeMsgIso9796 Method](#M_Rsa_DecodeMsgIso9796)

    + Decode a message padded using ISO/IEC 9796-1 formatting.
* [Rsa.Decrypt Method](#M_Rsa_Decrypt)

    + Decrypt a message encrypted using an RSA encryption scheme.
* [Rsa.EncodeDigestForSignature Method](#M_Rsa_EncodeDigestForSignature)

    + Encode a message digest for signature.
* [Rsa.EncodeMsgForEncryption Method](#M_Rsa_EncodeMsgForEncryption)

    + Encode a message for encryption.
* [Rsa.EncodeMsgForSignature Method](#M_Rsa_EncodeMsgForSignature)

    + Encode a message for signature.
* [Rsa.EncodeMsgIso9796 Method](#M_Rsa_EncodeMsgIso9796)

    + Encode a message using ISO/IEC 9796-1 formatting.
* [Rsa.Encrypt Method](#M_Rsa_Encrypt)

    + Encrypt a short message using RSA encryption.
* [Rsa.FromXMLString Method ](#M_Rsa_FromXMLString_String) (String)

    + Create an RSA key string in internal format from an XML string.
* [Rsa.FromXMLString Method ](#M_Rsa_FromXMLString_StringRsa_XmlOptions) (String, Rsa.XmlOptions)

    + Create an RSA key string in internal format from an XML string with options.
* [Rsa.FromXMLString Method ](#M_Rsa_FromXMLString_StringBoolean) (String, Boolean)

    + Create an RSA key string in internal format from an XML string with flag to exclude private key details.
* [Rsa.GetPrivateKeyFromPFX Method](#M_Rsa_GetPrivateKeyFromPFX)

    + Extract an encrypted private key from a PKCS-12 PKCS8ShroudedKeyBag, saving the output directly as a new file.
* [Rsa.GetPublicKeyFromCert Method](#M_Rsa_GetPublicKeyFromCert)

    + Read public key from X.509 certificate into internal string format.
* [Rsa.KeyBits Method ](#M_Rsa_KeyBits_String) (String)

    + Return number of significant bits in RSA key modulus.
* [Rsa.KeyBits Method ](#M_Rsa_KeyBits_StringBuilder) (StringBuilder)

    + Return number of significant bits in RSA key modulus.
* [Rsa.KeyBytes Method ](#M_Rsa_KeyBytes_String) (String)

    + Return number of bytes (octets) in RSA key modulus.
* [Rsa.KeyBytes Method ](#M_Rsa_KeyBytes_StringBuilder) (StringBuilder)

    + Return number of bytes (octets) in RSA key modulus.
* [Rsa.KeyHashCode Method ](#M_Rsa_KeyHashCode_String) (String)

    + Compute the hash code of an "internal" RSA public or private key string.
* [Rsa.KeyHashCode Method ](#M_Rsa_KeyHashCode_StringBuilder) (StringBuilder)

    + Compute the hash code of an "internal" RSA public or private key string.
* [Rsa.KeyMatch Method ](#M_Rsa_KeyMatch_StringString) (String, String)

    + Verify that a pair of "internal" RSA private and public key strings are matched.
* [Rsa.KeyMatch Method ](#M_Rsa_KeyMatch_StringBuilderStringBuilder) (StringBuilder, StringBuilder)

    + Verify that a pair of "internal" RSA private and public key strings are matched.
* [Rsa.KeyValue Method](#M_Rsa_KeyValue)

    + Extract a base64-encoded RSA key value from internal key string
* [Rsa.MakeKeys Method ](#M_Rsa_MakeKeys_StringStringInt32Rsa_PublicExponentInt32StringCipherAlgorithmHashAlgorithmRsa_FormatBoolean) (String, String, Int32, Rsa.PublicExponent, Int32, String, CipherAlgorithm, HashAlgorithm, Rsa.Format, Boolean)

    + Generate an RSA public/private key pair with extended options for encrypting private key [DEPRECATED].
* [Rsa.MakeKeys Method ](#M_Rsa_MakeKeys_StringStringInt32Rsa_PublicExponentInt32StringRsa_PbeOptionsBooleanByte) (String, String, Int32, Rsa.PublicExponent, Int32, String, Rsa.PbeOptions, Boolean, Byte[])

    + Generate an RSA public/private key pair [DEPRECATED].
* [Rsa.MakeKeys Method ](#M_Rsa_MakeKeys_StringStringStringInt32Rsa_PublicExponentRsa_PbeOptionsStringRsa_FormatBoolean) (String, String, String, Int32, Rsa.PublicExponent, Rsa.PbeOptions, String, Rsa.Format, Boolean)

    + Generate an RSA public/private key pair.
* [Rsa.PublicKeyFromPrivate Method](#M_Rsa_PublicKeyFromPrivate)

    + Convert an internal private key string into a public one.
* [Rsa.RawPrivate Method ](#M_Rsa_RawPrivate_ByteString) (Byte[], String)

    + Carry out RSA transformation using private key.
* [Rsa.RawPrivate Method ](#M_Rsa_RawPrivate_ByteStringInt32) (Byte[], String, Int32)

    + Carry out RSA transformation using private key (with specialist options).
* [Rsa.RawPublic Method ](#M_Rsa_RawPublic_ByteString) (Byte[], String)

    + Carry out RSA transformation using public key.
* [Rsa.RawPublic Method ](#M_Rsa_RawPublic_ByteStringInt32) (Byte[], String, Int32)

    + Carry out RSA transformation using public key (with specialist options).
* [Rsa.ReadEncPrivateKey Method](#M_Rsa_ReadEncPrivateKey)

    + Read encrypted private key file into internal string format.
* [Rsa.ReadPrivateKey Method](#M_Rsa_ReadPrivateKey)

    + Read from a file or string containing a private key into an "internal" private key string.
* [Rsa.ReadPrivateKeyFromPFX Method](#M_Rsa_ReadPrivateKeyFromPFX)

    + Read a private key directly from an encrypted PFX/PKCS-12 file into an "internal" private key string.
* [Rsa.ReadPrivateKeyInfo Method](#M_Rsa_ReadPrivateKeyInfo)

    + Read from an (unencrypted) PKCS-8 private key info file into a private key string.
* [Rsa.ReadPublicKey Method](#M_Rsa_ReadPublicKey)

    + Read from a file or string containing a public key into an "internal" public key string.
* [Rsa.SaveEncKey Method](#M_Rsa_SaveEncKey)

    + Save an internal RSA key string to an encrypted key file.
* [Rsa.SaveEncPrivateKey Method ](#M_Rsa_SaveEncPrivateKey_StringStringInt32StringCipherAlgorithmHashAlgorithmRsa_Format) (String, String, Int32, String, CipherAlgorithm, HashAlgorithm, Rsa.Format)

    + Save a private key string to a PKCS-8 EncryptedPrivateKeyInfo file using PBES2 algorithm [DEPRECATED].
* [Rsa.SaveEncPrivateKey Method ](#M_Rsa_SaveEncPrivateKey_StringStringInt32StringRsa_PbeOptionsRsa_Format) (String, String, Int32, String, Rsa.PbeOptions, Rsa.Format)

    + Save a private key string to a PKCS-8 EncryptedPrivateKeyInfo file [DEPRECATED].
* [Rsa.SavePrivateKeyInfo Method](#M_Rsa_SavePrivateKeyInfo)

    + Save a private key string to an (unencrypted) PKCS-8 private key info file.
* [Rsa.SavePublicKey Method](#M_Rsa_SavePublicKey)

    + Save a public key string to PKCS-1 public key file.
* [Rsa.ToXMLString Method ](#M_Rsa_ToXMLString_StringRsa_XmlOptions) (String, Rsa.XmlOptions)

    + Create an XML string representation of an RSA internal key string.
* [Rsa.ToXMLString Method ](#M_Rsa_ToXMLString_StringStringRsa_XmlOptions) (String, String, Rsa.XmlOptions)

    + Create an XML string representation of an RSA internal key string with option to add a namespace prefix.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Sig"></a>Sig Class

* [Sig.GetHashAlgFromSigAlg Method](#M_Sig_GetHashAlgFromSigAlg)

    + Get the hash algorithm used in the signature algorithm.
* [Sig.SignData Method](#M_Sig_SignData)

    + Compute a signature value over data in a byte array.
* [Sig.SignDigest Method](#M_Sig_SignDigest)

    + Compute a signature value over a message digest value.
* [Sig.SignFile Method](#M_Sig_SignFile)

    + Compute a signature value over binary data in a file.
* [Sig.VerifyData Method](#M_Sig_VerifyData)

    + Verify a signature value over data in a byte array.
* [Sig.VerifyDigest Method](#M_Sig_VerifyDigest)

    + Verify a signature value over a message digest value of data.
* [Sig.VerifyFile Method](#M_Sig_VerifyFile)

    + Verify a signature value over data in a file.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Smime"></a>Smime Class

* [Smime.Extract Method](#M_Smime_Extract)

    + Extract the body from an S/MIME entity.
* [Smime.Query Method](#M_Smime_Query)

    + Query an S/MIME entity for selected information.
* [Smime.Wrap Method](#M_Smime_Wrap)

    + Wrap a CMS object in an S/MIME entity.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Tdea"></a>Tdea Class

* [Tdea.Decrypt Method ](#M_Tdea_Decrypt_ByteByteModeByte) (Byte[], Byte[], Mode, Byte[])

    + Decrypt data in byte array.
* [Tdea.Decrypt Method ](#M_Tdea_Decrypt_StringStringModeString) (String, String, Mode, String)

    + Decrypt hex-encoded data string.
* [Tdea.Decrypt Method ](#M_Tdea_Decrypt_StringStringModeStringEncodingBase) (String, String, Mode, String, EncodingBase)

    + Decrypt encoded data string.
* [Tdea.Encrypt Method ](#M_Tdea_Encrypt_ByteByteModeByte) (Byte[], Byte[], Mode, Byte[])

    + Encrypt data in byte array.
* [Tdea.Encrypt Method ](#M_Tdea_Encrypt_StringStringModeString) (String, String, Mode, String)

    + Encrypt hex-encoded data string.
* [Tdea.Encrypt Method ](#M_Tdea_Encrypt_StringStringModeStringEncodingBase) (String, String, Mode, String, EncodingBase)

    + Encrypt encoded data string.
* [Tdea.FileDecrypt Method ](#M_Tdea_FileDecrypt_StringStringByteModeByte) (String, String, Byte[], Mode, Byte[])

    + Decrypt a file.
* [Tdea.FileDecrypt Method ](#M_Tdea_FileDecrypt_StringStringStringModeString) (String, String, String, Mode, String)

    + Decrypt a file passing key and IV as hex strings.
* [Tdea.FileEncrypt Method ](#M_Tdea_FileEncrypt_StringStringByteModeByte) (String, String, Byte[], Mode, Byte[])

    + Encrypt a file.
* [Tdea.FileEncrypt Method ](#M_Tdea_FileEncrypt_StringStringStringModeString) (String, String, String, Mode, String)

    + Encrypt a file passing key and IV as hex strings.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Wipe"></a>Wipe Class

* [Wipe.Data Method](#M_Wipe_Data)

    + Zeroise data in memory.
* [Wipe.File Method](#M_Wipe_File)

    + Securely wipe and delete a file with options.
* [Wipe.String Method](#M_Wipe_String)

    + Zeroise a StringBuilder.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_X509"></a>X509 Class

* [X509.CertExpiresOn Method](#M_X509_CertExpiresOn)

    + Return date and time certificate expires.
* [X509.CertIssuedOn Method](#M_X509_CertIssuedOn)

    + Return date and time certificate was issued.
* [X509.CertIssuerName Method](#M_X509_CertIssuerName)

    + Get the issuer name of an X.509 certificate.
* [X509.CertIsValidNow Method](#M_X509_CertIsValidNow)

    + Verify that an X.509 certificate is currently valid as per system clock.
* [X509.CertRequest Method](#M_X509_CertRequest)

    + Create a PKCS #10 certificate signing request (CSR).
* [X509.CertSerialNumber Method](#M_X509_CertSerialNumber)

    + Return serial number in hex format.
* [X509.CertSubjectName Method](#M_X509_CertSubjectName)

    + Get the subject name of an X.509 certificate.
* [X509.CertThumb Method](#M_X509_CertThumb)

    + Calculate the thumbprint (message digest hash) of an X.509 certificate.
* [X509.CheckCertInCRL Method](#M_X509_CheckCertInCRL)

    + Check whether an X.509 certificate has been revoked in a Certificate Revocation List (CRL).
* [X509.GetCertCountInP7Chain Method](#M_X509_GetCertCountInP7Chain)

    + Return number of certificates in a PKCS-7 "certs-only" certificate chain file.
* [X509.GetCertFromP7Chain Method](#M_X509_GetCertFromP7Chain)

    + Extract an X.509 certificate from a PKCS-7 "certs-only" certificate chain file, saving the output directly as a new file.
* [X509.GetCertFromPFX Method](#M_X509_GetCertFromPFX)

    + Extract an X.509 certificate from a PKCS-12 PFX/.p12 file, saving the output directly as a new file.
* [X509.GetP7ChainFromPFX Method](#M_X509_GetP7ChainFromPFX)

    + Extract all X.509 certificates from a PKCS-12 PFX/.p12 file, saving the output directly as a new PKCS-7 "certs-only" certificate chain file.
* [X509.HashIssuerAndSN Method](#M_X509_HashIssuerAndSN)

    + Create a message digest of the Issuer's name and the cert serial number.
* [X509.KeyUsageFlags Method](#M_X509_KeyUsageFlags)

    + Returns a bitfield containing the keyUsage flags.
* [X509.MakeCert Method](#M_X509_MakeCert)

    + Create a new X.509 certificate using subject's public key and issuer's private key files with signature options.
* [X509.MakeCertSelf Method](#M_X509_MakeCertSelf)

    + Create a self-signed X.509 certificate with signature options.
* [X509.MakeCRL Method](#M_X509_MakeCRL)

    + Create an X.509 Certificate Revocation List (CRL).
* [X509.QueryCert Method](#M_X509_QueryCert)

    + Query an X.509 certificate file for selected information.
* [X509.ReadCertStringFromP7Chain Method](#M_X509_ReadCertStringFromP7Chain)

    + Read an X.509 certificate into a base64 string from PKCS-7 "certs-only" data.
* [X509.ReadCertStringFromPFX Method](#M_X509_ReadCertStringFromPFX)

    + Read an X.509 certificate into a base64 string from PKCS-12 PFX/.p12 data.
* [X509.ReadStringFromFile Method](#M_X509_ReadStringFromFile)

    + Create a base64 string representation of a X.509 certificate file.
* [X509.SaveFileFromString Method](#M_X509_SaveFileFromString)

    + Create a new X.509 certificate file from a base64 string representation.
* [X509.TextDump Method](#M_X509_TextDump)

    + Dump details of an X.509 certificate or a X.509 certificate revocation list (CRL) or a PKCS-10 certificate signing request (CSR) to a text file.
* [X509.TextDumpToString Method](#M_X509_TextDumpToString)

    + Dump details of an X.509 certificate or a X.509 certificate revocation list (CRL) or a PKCS-10 certificate signing request (CSR) to a string.
* [X509.ValidatePath Method](#M_X509_ValidatePath)

    + Validate a certificate path.
* [X509.VerifyCert Method](#M_X509_VerifyCert)

    + Verify that an X.509 certificate has been signed by its issuer.

[[Contents](#topofpage)] [[Index](#index)]

### <a id="mx_Xof"></a>Xof Class

* [Xof.Bytes Method](#M_Xof_Bytes)

    + Generate bytes using an eXtendable-Output Function (XOF).

[[Contents](#topofpage)] [[Index](#index)]

<a id="methodlist"></a>List of .Net Methods
-------------------------------------------

Class index:   
[Asn1](#mx_Asn1) |
[Cipher](#mx_Cipher) |
[Cms](#mx_Cms) |
[Cnv](#mx_Cnv) |
[Compr](#mx_Compr) |
[Ecc](#mx_Ecc) |
[General](#mx_General) |
[Hash](#mx_Hash) |
[Hmac](#mx_Hmac) |
[Hpke](#mx_Hpke) |
[Kdf](#mx_Kdf) |
[Ocsp](#mx_Ocsp) |
[Pbe](#mx_Pbe) |
[Pem](#mx_Pem) |
[Pfx](#mx_Pfx) |
[Prf](#mx_Prf) |
[Pwd](#mx_Pwd) |
[Rng](#mx_Rng) |
[Rsa](#mx_Rsa) |
[Sig](#mx_Sig) |
[Smime](#mx_Smime) |
[Tdea](#mx_Tdea) |
[Wipe](#mx_Wipe) |
[X509](#mx_X509) |
[Xof](#mx_Xof)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Asn1_TextDump"></a>Asn1.TextDump Method

 Dump details of an ASN.1 formatted data file to a text file. 

#### Syntax

[`C#`]

```
public static int TextDump(
	string outputFile,
	string fileOrPEMString,
	Asn1.Options options
)
```

[`VB.NET`]

```
Public Shared Function TextDump ( _
	outputFile As String, _
	fileOrPEMString As String, _
	options As Asn1.Options _
) As Integer
```

#### Parameters

outputFile

:   Filename of text file to be created

fileOrPEMString

:   Filename of ASN.1 formatted data file to be analyzed (or a string containing its base64 or PEM representation)

options

:   Type: [Asn1.Options](#T_Asn1_Options)  

Option flags (optional)

#### Return Value

Zero if successful; otherwise it returns an [error code](#errorcodes)

#### See Also

VB6/C equivalent: [`ASN1_TextDump`](#ASN1_TextDump)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Asn1_TextDumpToString"></a>Asn1.TextDumpToString Method

 Dump details of ASN.1 formatted data to a string. 

#### Syntax

[`C#`]

```
public static string TextDumpToString(
	string fileOrPEMString,
	Asn1.Options options
)
```

[`VB.NET`]

```
Public Shared Function TextDumpToString ( _
	fileOrPEMString As String, _
	options As Asn1.Options _
) As String
```

#### Parameters

fileOrPEMString

:   Filename of ASN.1 formatted data file to be analyzed (or a string containing its base64 or PEM representation)

options

:   Type: [Asn1.Options](#T_Asn1_Options)  

Option flags: set as zero for defaults.

#### Return Value

String containing the output.

#### Remarks

This function creates a temporary file in the system TEMP directory. This file is locked and is automatically deleted after use.

#### See Also

VB6/C equivalent: [`ASN1_TextDumpToString`](#ASN1_TextDumpToString)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Asn1_Type"></a>Asn1.Type Method

 Describe the type of ASN.1 data. 

#### Syntax

[`C#`]

```
public static string Type(
	string fileOrPEMString
)
```

[`VB.NET`]

```
Public Shared Function Type ( _
	fileOrPEMString As String _
) As String
```

#### Parameters

fileOrPEMString

:   Filename of ASN.1 formatted data file to be analyzed (or a string containing its base64 or PEM representation)

#### Return Value

String containing the name of the type of ASN.1 data or the empty string if not found

#### See Also

VB6/C equivalent: [`ASN1_Type`](#ASN1_Type)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_BlockBytes"></a>Cipher.BlockBytes Method

 Return the block size in bytes for a given cipher algorithm. 

#### Syntax

[`C#`]

```
public static int BlockBytes(
	CipherAlgorithm alg
)
```

[`VB.NET`]

```
Public Shared Function BlockBytes ( _
	alg As CipherAlgorithm _
) As Integer
```

#### Parameters

alg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Cipher algorithm

#### Return Value

Block size in bytes

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_Decrypt_ByteByteByteCipherAlgorithmMode"></a>Cipher.Decrypt Method (Byte[], Byte[], Byte[], CipherAlgorithm, Mode)

 Decrypt data block in byte array. 

#### Syntax

[`C#`]

```
public static byte[] Decrypt(
	byte[] input,
	byte[] key,
	byte[] iv,
	CipherAlgorithm cipherAlg,
	Mode mode
)
```

[`VB.NET`]

```
Public Shared Function Decrypt ( _
	input As Byte(), _
	key As Byte(), _
	iv As Byte(), _
	cipherAlg As CipherAlgorithm, _
	mode As Mode _
) As Byte()
```

#### Parameters

input

:   Input data to be decrypted

key

:   Key of exact length for block cipher algorithm

iv

:   Initialization Vector (IV) of exactly the block size or null for ECB mode

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Cipher algorithm

mode

:   Type: [Mode](#T_Mode)  

Cipher mode

#### Return Value

Decrypted data in byte array or empty array on error

#### Remarks

For ECB and CBC modes, input data length **must** be an exact multiple of the block length.

#### See Also

VB6/C equivalent: [`CIPHER_Bytes`](#CIPHER_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_Decrypt_ByteByteByteCipherAlgorithmModePaddingCipher_Opts"></a>Cipher.Decrypt Method (Byte[], Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)

 Decrypt data in a byte array using the specified block cipher algorithm, mode and padding. 

#### Syntax

[`C#`]

```
public static byte[] Decrypt(
	byte[] input,
	byte[] key,
	byte[] iv,
	CipherAlgorithm cipherAlg,
	Mode mode,
	Padding pad,
	Cipher.Opts opts
)
```

[`VB.NET`]

```
Public Shared Function Decrypt ( _
	input As Byte(), _
	key As Byte(), _
	iv As Byte(), _
	cipherAlg As CipherAlgorithm, _
	mode As Mode, _
	pad As Padding, _
	opts As Cipher.Opts _
) As Byte()
```

#### Parameters

input

:   Input data to be decrypted

key

:   Key of exact length for block cipher algorithm

iv

:   Initialization Vector (IV) of exactly the block size, or null for ECB mode or if IV is prefixed.

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Cipher algorithm

mode

:   Type: [Mode](#T_Mode)  

Cipher mode

pad

:   Type: [Padding](#T_Padding)  

Padding method to use

opts

:   Type: [Cipher.Opts](#T_Cipher_Opts)  

Advanced options. Use Cipher.Opts.PrefixIV to expect the IV to be prepended to the input.

#### Return Value

Decrypted plaintext in byte array or empty array on error

#### Remarks

Default padding is Pkcs5 for ECB and CBC mode and NoPad for all other modes. It is an error if the specified padding is not found after decryption.

#### See Also

VB6/C equivalent: [`CIPHER_DecryptBytes`](#CIPHER_DecryptBytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_Decrypt_StringStringStringCipherAlgorithmMode"></a>Cipher.Decrypt Method (String, String, String, CipherAlgorithm, Mode)

 Decrypt data block as hex-encoded string. 

#### Syntax

[`C#`]

```
public static string Decrypt(
	string inputHex,
	string keyHex,
	string ivHex,
	CipherAlgorithm cipherAlg,
	Mode mode
)
```

[`VB.NET`]

```
Public Shared Function Decrypt ( _
	inputHex As String, _
	keyHex As String, _
	ivHex As String, _
	cipherAlg As CipherAlgorithm, _
	mode As Mode _
) As String
```

#### Parameters

inputHex

:   Hex-encoded input data

keyHex

:   Hex-encoded key representing exact key length

ivHex

:   Hex-encoded IV representing exact block length or "" for ECB mode

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Cipher Algorithm

mode

:   Type: [Mode](#T_Mode)  

Cipher Mode

#### Return Value

Decrypted plaintext in hex-encoded string or empty string on error

#### Remarks

For ECB and CBC modes, input data length **must** represent an exact multiple of the block length.

#### See Also

VB6/C equivalent: [`CIPHER_Hex`](#CIPHER_Hex)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_Decrypt_StringStringStringCipherAlgorithmModePaddingCipher_Opts"></a>Cipher.Decrypt Method (String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts)

 Decrypt hex-encoded data using specified block cipher algorithm, mode and padding. 

#### Syntax

[`C#`]

```
public static string Decrypt(
	string inputHex,
	string keyHex,
	string ivHex,
	CipherAlgorithm cipherAlg,
	Mode mode,
	Padding pad,
	Cipher.Opts opts
)
```

[`VB.NET`]

```
Public Shared Function Decrypt ( _
	inputHex As String, _
	keyHex As String, _
	ivHex As String, _
	cipherAlg As CipherAlgorithm, _
	mode As Mode, _
	pad As Padding, _
	opts As Cipher.Opts _
) As String
```

#### Parameters

inputHex

:   Hex-encoded input data

keyHex

:   Hex-encoded key representing exact key length

ivHex

:   Hex-encoded IV representing exact block length, or "" for ECB mode or if IV is prefixed.

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Cipher Algorithm

mode

:   Type: [Mode](#T_Mode)  

Cipher Mode

pad

:   Type: [Padding](#T_Padding)  

Padding method to use

opts

:   Type: [Cipher.Opts](#T_Cipher_Opts)  

Advanced options. Use Cipher.Opts.PrefixIV to expect the IV to be prepended to the input.

#### Return Value

Decrypted plaintex in hex-encoded string or empty string on error

#### Remarks

Input data may be any even number of hex characters, but not zero. Default padding is Pkcs5 for ECB and CBC mode and NoPad for all other modes.

#### See Also

VB6/C equivalent: [`CIPHER_DecryptHex`](#CIPHER_DecryptHex)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_DecryptAEAD_ByteByteByteAeadAlgorithm"></a>Cipher.DecryptAEAD Method (Byte[], Byte[], Byte[], AeadAlgorithm)

 Decrypt data using the AES-GCM authenticated encryption algorithm. 

#### Syntax

[`C#`]

```
public static byte[] DecryptAEAD(
	byte[] input,
	byte[] key,
	byte[] iv,
	AeadAlgorithm aeadAlg
)
```

[`VB.NET`]

```
Public Shared Function DecryptAEAD ( _
	input As Byte(), _
	key As Byte(), _
	iv As Byte(), _
	aeadAlg As AeadAlgorithm _
) As Byte()
```

#### Parameters

input

:   Input data to be decrypted.

key

:   Key of exact length for algorithm (16, 24 or 32 bytes).

iv

:   Initialization Vector (IV) (aka nonce) exactly 12 bytes long.

aeadAlg

:   Type: [AeadAlgorithm](#T_AeadAlgorithm)  

Authenticated encryption algorithm.

#### Return Value

Plaintext in a byte array, or empty array on error (an empty array may also be the correct result - check General.ErrorCode for details).

#### Remarks

The input *must* include the 16-byte tag appended to the ciphertext. The output will be exactly 16 bytes shorter than the input. In all cases the IV *must* be exactly 12 bytes (96 bits) and the tag *must* be exactly 16 bytes (128 bits).

#### See Also

VB6/C equivalent: [`CIPHER_DecryptAEAD`](#CIPHER_DecryptAEAD)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_DecryptAEAD_ByteByteByteByteAeadAlgorithmCipher_Opts"></a>Cipher.DecryptAEAD Method (Byte[], Byte[], Byte[], Byte[], AeadAlgorithm, Cipher.Opts)

 Decrypt data using the AES-GCM authenticated encryption algorithm with AAD and options. 

#### Syntax

[`C#`]

```
public static byte[] DecryptAEAD(
	byte[] input,
	byte[] key,
	byte[] iv,
	byte[] aad,
	AeadAlgorithm aeadAlg,
	Cipher.Opts opts
)
```

[`VB.NET`]

```
Public Shared Function DecryptAEAD ( _
	input As Byte(), _
	key As Byte(), _
	iv As Byte(), _
	aad As Byte(), _
	aeadAlg As AeadAlgorithm, _
	opts As Cipher.Opts _
) As Byte()
```

#### Parameters

input

:   Input data to be decrypted.

key

:   Key of exact length for algorithm (16, 24 or 32 bytes).

iv

:   Initialization Vector (IV) (aka nonce) exactly 12 bytes long, if not provided in input.

aad

:   Additional authenticated data (optional) - set as null to ignore.

aeadAlg

:   Type: [AeadAlgorithm](#T_AeadAlgorithm)  

Authenticated encryption algorithm.

opts

:   Type: [Cipher.Opts](#T_Cipher_Opts)  

Advanced options. Use Cipher.Opts.PrefixIV to expect the IV to be prepended at the start of the input.

#### Return Value

Plaintext in a byte array, or empty array on error (an empty array may also be the correct result - check General.ErrorCode for details).

#### Remarks

The input *must* include the 16-byte tag appended to the ciphertext and may include a 12-byte prefixed IV. The output will either be exactly 16 bytes shorter than the input, or exactly 28 bytes shorter if the Cipher.Opts.PrefixIV option is used. In all cases the IV *must* be exactly 12 bytes (96 bits) and the tag *must* be exactly 16 bytes (128 bits). If additional authentication data (AAD) was provided during encryption then the exact same AAD data must be provided here.

#### See Also

VB6/C equivalent: [`CIPHER_DecryptAEAD`](#CIPHER_DecryptAEAD)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_Encrypt_ByteByteByteCipherAlgorithmMode"></a>Cipher.Encrypt Method (Byte[], Byte[], Byte[], CipherAlgorithm, Mode)

 Encrypt data block in byte array. 

#### Syntax

[`C#`]

```
public static byte[] Encrypt(
	byte[] input,
	byte[] key,
	byte[] iv,
	CipherAlgorithm cipherAlg,
	Mode mode
)
```

[`VB.NET`]

```
Public Shared Function Encrypt ( _
	input As Byte(), _
	key As Byte(), _
	iv As Byte(), _
	cipherAlg As CipherAlgorithm, _
	mode As Mode _
) As Byte()
```

#### Parameters

input

:   Input data to be encrypted

key

:   Key of exact length for block cipher algorithm

iv

:   Initialization Vector (IV) of exactly the block size or null for ECB mode

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Cipher algorithm

mode

:   Type: [Mode](#T_Mode)  

Cipher mode

#### Return Value

Ciphertext in byte array or empty array on error

#### Remarks

For ECB and CBC modes, input data length **must** be an exact multiple of the block length.

#### See Also

VB6/C equivalent: [`CIPHER_Bytes`](#CIPHER_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_Encrypt_ByteByteByteCipherAlgorithmModePaddingCipher_Opts"></a>Cipher.Encrypt Method (Byte[], Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)

 Encrypt data in a byte array using the specified block cipher algorithm, mode and padding. 

#### Syntax

[`C#`]

```
public static byte[] Encrypt(
	byte[] input,
	byte[] key,
	byte[] iv,
	CipherAlgorithm cipherAlg,
	Mode mode,
	Padding pad,
	Cipher.Opts opts
)
```

[`VB.NET`]

```
Public Shared Function Encrypt ( _
	input As Byte(), _
	key As Byte(), _
	iv As Byte(), _
	cipherAlg As CipherAlgorithm, _
	mode As Mode, _
	pad As Padding, _
	opts As Cipher.Opts _
) As Byte()
```

#### Parameters

input

:   Input data to be encrypted

key

:   Key of exact length for block cipher algorithm

iv

:   Initialization Vector (IV) of exactly the block size or null for ECB mode.

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Cipher algorithm

mode

:   Type: [Mode](#T_Mode)  

Cipher mode

pad

:   Type: [Padding](#T_Padding)  

Padding method to use

opts

:   Type: [Cipher.Opts](#T_Cipher_Opts)  

Advanced options. Use Cipher.Opts.PrefixIV to prepend the IV to the output.

#### Return Value

Ciphertext in byte array or empty array on error

#### Remarks

Default padding is Pkcs5 for ECB and CBC mode and NoPad for all other modes.

#### See Also

VB6/C equivalent: [`CIPHER_EncryptBytes`](#CIPHER_EncryptBytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_Encrypt_StringStringStringCipherAlgorithmMode"></a>Cipher.Encrypt Method (String, String, String, CipherAlgorithm, Mode)

 Encrypt data block as hex-encoded string. 

#### Syntax

[`C#`]

```
public static string Encrypt(
	string inputHex,
	string keyHex,
	string ivHex,
	CipherAlgorithm cipherAlg,
	Mode mode
)
```

[`VB.NET`]

```
Public Shared Function Encrypt ( _
	inputHex As String, _
	keyHex As String, _
	ivHex As String, _
	cipherAlg As CipherAlgorithm, _
	mode As Mode _
) As String
```

#### Parameters

inputHex

:   Hex-encoded input data

keyHex

:   Hex-encoded key representing exact key length

ivHex

:   Hex-encoded IV representing exact block length or "" for ECB mode

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Cipher algorithm

mode

:   Type: [Mode](#T_Mode)  

Cipher mode

#### Return Value

Ciphertext in hex-encoded string or empty string on error

#### Remarks

For ECB and CBC modes, input data length **must** be an exact multiple of the block length.

#### See Also

VB6/C equivalent: [`CIPHER_Hex`](#CIPHER_Hex)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_Encrypt_StringStringStringCipherAlgorithmModePaddingCipher_Opts"></a>Cipher.Encrypt Method (String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts)

 Encrypt hex-encoded data using specified block cipher algorithm, mode and padding. 

#### Syntax

[`C#`]

```
public static string Encrypt(
	string inputHex,
	string keyHex,
	string ivHex,
	CipherAlgorithm cipherAlg,
	Mode mode,
	Padding pad,
	Cipher.Opts opts
)
```

[`VB.NET`]

```
Public Shared Function Encrypt ( _
	inputHex As String, _
	keyHex As String, _
	ivHex As String, _
	cipherAlg As CipherAlgorithm, _
	mode As Mode, _
	pad As Padding, _
	opts As Cipher.Opts _
) As String
```

#### Parameters

inputHex

:   Hex-encoded input data

keyHex

:   Hex-encoded key representing exact key length

ivHex

:   Hex-encoded IV representing exact block length or "" for ECB mode

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Cipher Algorithm

mode

:   Type: [Mode](#T_Mode)  

Cipher Mode

pad

:   Type: [Padding](#T_Padding)  

Padding method to use (optional)

opts

:   Type: [Cipher.Opts](#T_Cipher_Opts)  

Advanced options. Use Cipher.Opts.PrefixIV to prepend the IV to the output.

#### Return Value

Encrypted ciphertext in hex-encoded string or empty string on error

#### Remarks

Input data may be any even number of hex characters, but not zero. Default padding is Pkcs5 for ECB and CBC mode and NoPad for all other modes.

#### See Also

VB6/C equivalent: [`CIPHER_EncryptHex`](#CIPHER_EncryptHex)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_EncryptAEAD_ByteByteByteAeadAlgorithm"></a>Cipher.EncryptAEAD Method (Byte[], Byte[], Byte[], AeadAlgorithm)

 Encrypt data using the AES-GCM authenticated encryption algorithm. 

#### Syntax

[`C#`]

```
public static byte[] EncryptAEAD(
	byte[] input,
	byte[] key,
	byte[] iv,
	AeadAlgorithm aeadAlg
)
```

[`VB.NET`]

```
Public Shared Function EncryptAEAD ( _
	input As Byte(), _
	key As Byte(), _
	iv As Byte(), _
	aeadAlg As AeadAlgorithm _
) As Byte()
```

#### Parameters

input

:   Input data to be encrypted.

key

:   Key of exact length for algorithm (16, 24 or 32 bytes).

iv

:   Initialization Vector (IV) (aka nonce) exactly 12 bytes long.

aeadAlg

:   Type: [AeadAlgorithm](#T_AeadAlgorithm)  

Authenticated encryption algorithm.

#### Return Value

Ciphertext with tag appended in a byte array, or empty array on error.

#### Remarks

The output will be exactly 16 bytes longer than the input.

#### See Also

VB6/C equivalent: [`CIPHER_EncryptAEAD`](#CIPHER_EncryptAEAD)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_EncryptAEAD_ByteByteByteByteAeadAlgorithmCipher_Opts"></a>Cipher.EncryptAEAD Method (Byte[], Byte[], Byte[], Byte[], AeadAlgorithm, Cipher.Opts)

 Encrypt data using the AES-GCM authenticated encryption algorithm with AAD and options. 

#### Syntax

[`C#`]

```
public static byte[] EncryptAEAD(
	byte[] input,
	byte[] key,
	byte[] iv,
	byte[] aad,
	AeadAlgorithm aeadAlg,
	Cipher.Opts opts
)
```

[`VB.NET`]

```
Public Shared Function EncryptAEAD ( _
	input As Byte(), _
	key As Byte(), _
	iv As Byte(), _
	aad As Byte(), _
	aeadAlg As AeadAlgorithm, _
	opts As Cipher.Opts _
) As Byte()
```

#### Parameters

input

:   Input data to be encrypted.

key

:   Key of exact length for algorithm (16, 24 or 32 bytes).

iv

:   Initialization Vector (IV) (aka nonce) exactly 12 bytes long.

aad

:   Additional authenticated data (optional) - set as null to ignore.

aeadAlg

:   Type: [AeadAlgorithm](#T_AeadAlgorithm)  

Authenticated encryption algorithm.

opts

:   Type: [Cipher.Opts](#T_Cipher_Opts)  

Advanced options. Use Cipher.Opts.PrefixIV to prepend the 12-byte IV to the output

#### Return Value

Ciphertext with tag appended in a byte array, or empty array on error.

#### Remarks

The output will either be exactly 16 bytes longer than the input, or exactly 28 bytes longer if Cipher.Opts.PrefixIV is used.

#### See Also

VB6/C equivalent: [`CIPHER_EncryptAEAD`](#CIPHER_EncryptAEAD)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_FileDecrypt_StringStringByteByteCipherAlgorithmModePaddingCipher_Opts"></a>Cipher.FileDecrypt Method (String, String, Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)

 Decrypt a file. 

#### Syntax

[`C#`]

```
public static int FileDecrypt(
	string fileOut,
	string fileIn,
	byte[] key,
	byte[] iv,
	CipherAlgorithm cipherAlg,
	Mode mode,
	Padding pad,
	Cipher.Opts opts
)
```

[`VB.NET`]

```
Public Shared Function FileDecrypt ( _
	fileOut As String, _
	fileIn As String, _
	key As Byte(), _
	iv As Byte(), _
	cipherAlg As CipherAlgorithm, _
	mode As Mode, _
	pad As Padding, _
	opts As Cipher.Opts _
) As Integer
```

#### Parameters

fileOut

:   Name of output file to be created or overwritten

fileIn

:   Name of input file

key

:   Key of of exact length for block cipher algorithm

iv

:   Initialization Vector (IV) of exactly the block size, or null for ECB mode or if IV is prefixed.

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Cipher Algorithm

mode

:   Type: [Mode](#T_Mode)  

Cipher Mode

pad

:   Type: [Padding](#T_Padding)  

Padding method to use (optional, ECB and CBC modes only, default=Pkcs5)

opts

:   Type: [Cipher.Opts](#T_Cipher_Opts)  

Advanced options. Use Cipher.Opts.PrefixIV to expect the IV to be prepended to the input.

#### Return Value

0 if successful or non-zero [error code](#errorcodes)

#### Remarks

fileOut and fileIn must **not** be the same

#### See Also

VB6/C equivalent: [`CIPHER_FileDecrypt`](#CIPHER_FileDecrypt)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_FileDecrypt_StringStringStringStringCipherAlgorithmModePaddingCipher_Opts"></a>Cipher.FileDecrypt Method (String, String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts)

 Decrypt a file passing key and IV as hex strings. 

#### Syntax

[`C#`]

```
public static int FileDecrypt(
	string fileOut,
	string fileIn,
	string keyHex,
	string ivHex,
	CipherAlgorithm cipherAlg,
	Mode mode,
	Padding pad,
	Cipher.Opts opts
)
```

[`VB.NET`]

```
Public Shared Function FileDecrypt ( _
	fileOut As String, _
	fileIn As String, _
	keyHex As String, _
	ivHex As String, _
	cipherAlg As CipherAlgorithm, _
	mode As Mode, _
	pad As Padding, _
	opts As Cipher.Opts _
) As Integer
```

#### Parameters

fileOut

:   Name of output file to be created or overwritten

fileIn

:   Name of input file, in binary format.

keyHex

:   Hex-encoded key of exact length

ivHex

:   Hex-encoded IV, or "" for ECB mode or if IV is prefixed.

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Cipher Algorithm

mode

:   Type: [Mode](#T_Mode)  

Cipher Mode

pad

:   Type: [Padding](#T_Padding)  

Padding method to use (optional, ECB and CBC modes only, default=Pkcs5)

opts

:   Type: [Cipher.Opts](#T_Cipher_Opts)  

Advanced options. Use Cipher.Opts.PrefixIV to expect the IV to be prepended to the input.

#### Return Value

0 if successful or non-zero [error code](#errorcodes)

#### Remarks

fileOut and fileIn must **not** be the same. The output file is in binary format.

#### See Also

VB6/C equivalent: [`CIPHER_FileDecrypt`](#CIPHER_FileDecrypt)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_FileEncrypt_StringStringByteByteCipherAlgorithmModePaddingCipher_Opts"></a>Cipher.FileEncrypt Method (String, String, Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)

 Encrypt a file. 

#### Syntax

[`C#`]

```
public static int FileEncrypt(
	string fileOut,
	string fileIn,
	byte[] key,
	byte[] iv,
	CipherAlgorithm cipherAlg,
	Mode mode,
	Padding pad,
	Cipher.Opts opts
)
```

[`VB.NET`]

```
Public Shared Function FileEncrypt ( _
	fileOut As String, _
	fileIn As String, _
	key As Byte(), _
	iv As Byte(), _
	cipherAlg As CipherAlgorithm, _
	mode As Mode, _
	pad As Padding, _
	opts As Cipher.Opts _
) As Integer
```

#### Parameters

fileOut

:   Name of output file to be created or overwritten

fileIn

:   Name of input file

key

:   Key of of exact length for block cipher algorithm

iv

:   Initialization Vector (IV) of exactly the block size or null for ECB mode

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Cipher Algorithm

mode

:   Type: [Mode](#T_Mode)  

Cipher Mode

pad

:   Type: [Padding](#T_Padding)  

Padding method to use (optional, ECB and CBC modes only, default=Pkcs5)

opts

:   Type: [Cipher.Opts](#T_Cipher_Opts)  

Advanced options. Use Cipher.Opts.PrefixIV to prepend the IV to the output.

#### Return Value

0 if successful or non-zero [error code](#errorcodes)

#### Remarks

fileOut and fileIn must **not** be the same

#### See Also

VB6/C equivalent: [`CIPHER_FileEncrypt`](#CIPHER_FileEncrypt)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_FileEncrypt_StringStringStringStringCipherAlgorithmModePaddingCipher_Opts"></a>Cipher.FileEncrypt Method (String, String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts)

 Encrypt a file passing key and IV as hex strings. 

#### Syntax

[`C#`]

```
public static int FileEncrypt(
	string fileOut,
	string fileIn,
	string keyHex,
	string ivHex,
	CipherAlgorithm cipherAlg,
	Mode mode,
	Padding pad,
	Cipher.Opts opts
)
```

[`VB.NET`]

```
Public Shared Function FileEncrypt ( _
	fileOut As String, _
	fileIn As String, _
	keyHex As String, _
	ivHex As String, _
	cipherAlg As CipherAlgorithm, _
	mode As Mode, _
	pad As Padding, _
	opts As Cipher.Opts _
) As Integer
```

#### Parameters

fileOut

:   Name of output file to be created or overwritten

fileIn

:   Name of input file, in binary format.

keyHex

:   Hex-encoded key of exact length

ivHex

:   Hex-encoded IV or "" for ECB mode

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Cipher Algorithm

mode

:   Type: [Mode](#T_Mode)  

Cipher Mode

pad

:   Type: [Padding](#T_Padding)  

Padding method to use (optional, ECB and CBC modes only, default=Pkcs5)

opts

:   Type: [Cipher.Opts](#T_Cipher_Opts)  

Advanced options. Use Cipher.Opts.PrefixIV to prepend the IV to the output.

#### Return Value

0 if successful or non-zero [error code](#errorcodes)

#### Remarks

fileOut and fileIn must **not** be the same. The output file is in binary format.

#### See Also

VB6/C equivalent: [`CIPHER_FileEncrypt`](#CIPHER_FileEncrypt)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_KeyBytes"></a>Cipher.KeyBytes Method

 Return the key size in bytes for a given cipher algorithm. 

#### Syntax

[`C#`]

```
public static int KeyBytes(
	CipherAlgorithm alg
)
```

[`VB.NET`]

```
Public Shared Function KeyBytes ( _
	alg As CipherAlgorithm _
) As Integer
```

#### Parameters

alg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Cipher algorithm

#### Return Value

Key size in bytes

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_KeyUnwrap"></a>Cipher.KeyUnwrap Method

 Unwrap (decrypt) key material with a key-encryption key. 

#### Syntax

[`C#`]

```
public static byte[] KeyUnwrap(
	byte[] data,
	byte[] kek,
	CipherAlgorithm cipherAlg
)
```

[`VB.NET`]

```
Public Shared Function KeyUnwrap ( _
	data As Byte(), _
	kek As Byte(), _
	cipherAlg As CipherAlgorithm _
) As Byte()
```

#### Parameters

data

:   Wrapped key

kek

:   Key encryption key

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Block cipher to use for wrapping

#### Return Value

Unwrapped key material (or empty array on error)

#### See Also

VB6/C equivalent: [`CIPHER_KeyUnwrap`](#CIPHER_KeyUnwrap)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_KeyWrap"></a>Cipher.KeyWrap Method

 Wrap (encrypt) key material with a key-encryption key. 

#### Syntax

[`C#`]

```
public static byte[] KeyWrap(
	byte[] data,
	byte[] kek,
	CipherAlgorithm cipherAlg
)
```

[`VB.NET`]

```
Public Shared Function KeyWrap ( _
	data As Byte(), _
	kek As Byte(), _
	cipherAlg As CipherAlgorithm _
) As Byte()
```

#### Parameters

data

:   Key material to be wrapped

kek

:   Key encryption key

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Block cipher to use for wrapping

#### Return Value

Wrapped key (or empty array on error)

#### See Also

VB6/C equivalent: [`CIPHER_KeyWrap`](#CIPHER_KeyWrap)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_Pad_ByteCipherAlgorithmPadding"></a>Cipher.Pad Method (Byte[], CipherAlgorithm, Padding)

 Pad byte array to correct length for ECB and CBC encryption. 

#### Syntax

[`C#`]

```
public static byte[] Pad(
	byte[] input,
	CipherAlgorithm cipherAlg,
	Padding pad
)
```

[`VB.NET`]

```
Public Shared Function Pad ( _
	input As Byte(), _
	cipherAlg As CipherAlgorithm, _
	pad As Padding _
) As Byte()
```

#### Parameters

input

:   Data to be padded

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Block cipher being used

pad

:   Type: [Padding](#T_Padding)  

Padding method to use (default is PKCS#5/#7)

#### Return Value

Padded data in byte array

#### See Also

VB6/C equivalent: [`PAD_BytesBlock`](#PAD_BytesBlock)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_Pad_StringCipherAlgorithmPadding"></a>Cipher.Pad Method (String, CipherAlgorithm, Padding)

 Pad hex-encoded string to correct length for ECB and CBC encryption. 

#### Syntax

[`C#`]

```
public static string Pad(
	string inputHex,
	CipherAlgorithm cipherAlg,
	Padding pad
)
```

[`VB.NET`]

```
Public Shared Function Pad ( _
	inputHex As String, _
	cipherAlg As CipherAlgorithm, _
	pad As Padding _
) As String
```

#### Parameters

inputHex

:   Hex-encoded data to be padded

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Block cipher being used

pad

:   Type: [Padding](#T_Padding)  

Padding method to use (default is PKCS#5/#7)

#### Return Value

Padded data in hex-encoded string

#### See Also

VB6/C equivalent: [`PAD_HexBlock`](#PAD_HexBlock)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_Unpad_ByteCipherAlgorithmPadding"></a>Cipher.Unpad Method (Byte[], CipherAlgorithm, Padding)

 Remove padding from an encryption block. 

#### Syntax

[`C#`]

```
public static byte[] Unpad(
	byte[] input,
	CipherAlgorithm cipherAlg,
	Padding pad
)
```

[`VB.NET`]

```
Public Shared Function Unpad ( _
	input As Byte(), _
	cipherAlg As CipherAlgorithm, _
	pad As Padding _
) As Byte()
```

#### Parameters

input

:   Padded data

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Block cipher being used

pad

:   Type: [Padding](#T_Padding)  

Padding method to use (default is PKCS#5/#7)

#### Return Value

Unpadded data in byte array.

#### Remarks

Unless pad is NoPad, the unpadded output is *always* shorter than the padded input. An error is indicated by returning the *original* data. If the output length equals the input length, then error.

#### See Also

VB6/C equivalent: [`PAD_UnpadBytes`](#PAD_UnpadBytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cipher_Unpad_StringCipherAlgorithmPadding"></a>Cipher.Unpad Method (String, CipherAlgorithm, Padding)

 Remove padding from a hex-encoded encryption block. 

#### Syntax

[`C#`]

```
public static string Unpad(
	string inputHex,
	CipherAlgorithm cipherAlg,
	Padding pad
)
```

[`VB.NET`]

```
Public Shared Function Unpad ( _
	inputHex As String, _
	cipherAlg As CipherAlgorithm, _
	pad As Padding _
) As String
```

#### Parameters

inputHex

:   Hex-encoded padded data

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Block cipher being used

pad

:   Type: [Padding](#T_Padding)  

Padding method to use (default is PKCS#5/#7)

#### Return Value

Unpadded data in hex-encoded string.

#### Remarks

Unless pad is NoPad, the unpadded output is *always* shorter than the padded input. An error is indicated by returning the *original* data. If the output length equals the input length, then error.

#### See Also

VB6/C equivalent: [`PAD_UnpadHex`](#PAD_UnpadHex)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_GetSigDataDigest"></a>Cms.GetSigDataDigest Method

 Extract the message digest from a signed-data CMS object file and verify the signature. 

#### Syntax

[`C#`]

```
public static string GetSigDataDigest(
	string inputFile,
	string certFile
)
```

[`VB.NET`]

```
Public Shared Function GetSigDataDigest ( _
	inputFile As String, _
	certFile As String _
) As String
```

#### Parameters

inputFile

:   name of file containing CMS signed-data object

certFile

:   an (optional) X.509 certificate file to be used to identify the signer

#### Return Value

Hash value in hex format or an empty string if error

#### Remarks

If no certificate is given, it will use the first valid SignerInfo and certificate pair it finds in the SignedData. RSASSA-PKCS1V1_5 only.

#### See Also

VB6/C equivalent: [`CMS_GetSigDataDigest`](#CMS_GetSigDataDigest)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_GetSigHashAlgorithm"></a>Cms.GetSigHashAlgorithm Method

 Find ID of message digest hash algorithm used to make signature. 

#### Syntax

[`C#`]

```
public static int GetSigHashAlgorithm(
	string inputFile,
	string certFile
)
```

[`VB.NET`]

```
Public Shared Function GetSigHashAlgorithm ( _
	inputFile As String, _
	certFile As String _
) As Integer
```

#### Parameters

inputFile

:   name of file containing CMS signed-data object

certFile

:   an (optional) X.509 certificate file to be used to identify the signer

#### Return Value

0=SHA-1, 1=MD5, 2=MD2, 3=SHA-256, 4=SHA-384, 5=SHA-512, 6=SHA-224; or a negative [error code](#errorcodes)

#### Remarks

This method returns an integer ID number. Alternatively, use Cms.QuerySigData(inputFile, "digestAlgorithm") to get the name directly as a string, e.g. "sha1". See QuerySigData(String, String)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_MakeComprData"></a>Cms.MakeComprData Method

 Create a new CMS compressed-data file (.p7z) from an existing input file. 

#### Syntax

[`C#`]

```
public static int MakeComprData(
	string outputFile,
	string inputFile
)
```

[`VB.NET`]

```
Public Shared Function MakeComprData ( _
	outputFile As String, _
	inputFile As String _
) As Integer
```

#### Parameters

outputFile

:   Output file to be created

inputFile

:   Input data file

#### Return Value

Zero if successful; otherwise it returns a non-zero [error code](#errorcodes)

#### See Also

VB6/C equivalent: [`CMS_MakeComprData`](#CMS_MakeComprData)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_MakeDetachedSig"></a>Cms.MakeDetachedSig Method

 Create a "detached signature" CMS signed-data object file from a **message digest** of the content (advanced algorithms). 

#### Syntax

[`C#`]

```
public static int MakeDetachedSig(
	string outputFile,
	string hexDigest,
	string certList,
	string privateKey,
	HashAlgorithm hashAlg,
	Cms.SigDataOptions advOptions
)
```

[`VB.NET`]

```
Public Shared Function MakeDetachedSig ( _
	outputFile As String, _
	hexDigest As String, _
	certList As String, _
	privateKey As String, _
	hashAlg As HashAlgorithm, _
	advOptions As Cms.SigDataOptions _
) As Integer
```

#### Parameters

outputFile

:   name of output file to be created

hexDigest

:   string containing message digest in hex format

certList

:   filename of the signer's certificate and (optionally) a list of other certificates to be included in the output, separated by semi-colons (;) Alternatively specify a single PKCS#7 certificate chain file (.p7c/.p7b) containing the signer's certificate.

privateKey

:   Private key data for the sender.

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Message digest algorithm to be used in signature [default=SHA-1]

advOptions

:   Type: [Cms.SigDataOptions](#T_Cms_SigDataOptions)  

Advanced option flags. See Cms.SigDataOptions.

#### Return Value

Zero if successful; otherwise it returns an [error code](#errorcodes)

#### Remarks

RSASSA-PKCS1V1_5 only.

#### See Also

VB6/C equivalent: [`CMS_MakeDetachedSig`](#CMS_MakeDetachedSig)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_MakeEnvData_StringStringStringCipherAlgorithmCms_EnvDataOptions"></a>Cms.MakeEnvData Method (String, String, String, CipherAlgorithm, Cms.EnvDataOptions)

 Create a CMS enveloped-data object (default recipient parameters). 

#### Syntax

[`C#`]

```
public static int MakeEnvData(
	string outputFile,
	string inputFile,
	string certList,
	CipherAlgorithm cipherAlg,
	Cms.EnvDataOptions advOptions
)
```

[`VB.NET`]

```
Public Shared Function MakeEnvData ( _
	outputFile As String, _
	inputFile As String, _
	certList As String, _
	cipherAlg As CipherAlgorithm, _
	advOptions As Cms.EnvDataOptions _
) As Integer
```

#### Parameters

outputFile

:   Name of output file to be created.

inputFile

:   Input data file.

certList

:   List of recipient X.509 certificate filename(s), separated by semi-colons (;). Alternatively, specify a single PKCS#7 certificate chain file (.p7c/.p7b).

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Content encryption algorithm [default=Triple DES].

advOptions

:   Type: [Cms.EnvDataOptions](#T_Cms_EnvDataOptions)  

Advanced options. See Cms.EnvDataOptions.

#### Return Value

Number of successful recipients or a negative [error code](#errorcodes).

#### See Also

VB6/C equivalent: [`CMS_MakeEnvData`](#CMS_MakeEnvData)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_MakeEnvData_StringStringStringCipherAlgorithmCms_KeyEncrAlgorithmHashAlgorithmCms_EnvDataOptionsKdf_KdfAlgKdf_KeyWrapAlgStringInt32Cms_ContentEncrAlg"></a>Cms.MakeEnvData Method (String, String, String, CipherAlgorithm, Cms.KeyEncrAlgorithm, HashAlgorithm, Cms.EnvDataOptions, Kdf.KdfAlg, Kdf.KeyWrapAlg, String, Int32, Cms.ContentEncrAlg)

 Create a CMS enveloped-data object (advanced options). 

#### Syntax

[`C#`]

```
public static int MakeEnvData(
	string outputFile,
	string inputFile,
	string certList,
	CipherAlgorithm cipherAlg,
	Cms.KeyEncrAlgorithm keyEncrAlg,
	HashAlgorithm hashAlg,
	Cms.EnvDataOptions advOptions,
	Kdf.KdfAlg kdfAlg,
	Kdf.KeyWrapAlg keyWrapAlg,
	string keyString,
	int count,
	Cms.ContentEncrAlg contEncrAlg
)
```

[`VB.NET`]

```
Public Shared Function MakeEnvData ( _
	outputFile As String, _
	inputFile As String, _
	certList As String, _
	cipherAlg As CipherAlgorithm, _
	keyEncrAlg As Cms.KeyEncrAlgorithm, _
	hashAlg As HashAlgorithm, _
	advOptions As Cms.EnvDataOptions, _
	kdfAlg As Kdf.KdfAlg, _
	keyWrapAlg As Kdf.KeyWrapAlg, _
	keyString As String, _
	count As Integer, _
	contEncrAlg As Cms.ContentEncrAlg _
) As Integer
```

#### Parameters

outputFile

:   Name of output file to be created.

inputFile

:   Input data file.

certList

:   List of one or more recipient X.509 certificate filenames, separated by semicolons (;). A certificate's representation in base64 or as a PEM string may be used instead of a filename. Alternatively, specify a single PKCS#7 certificate chain file (.p7c/.p7b). 

*Special cases:* Set as "type=@pwri" to create a single recipientInfo of the PasswordRecipientInfo (pwri) type; or set as "type=@kekri,keyid=<string>" to create a single recipientInfo of the KEKRecipientInfo (kekri) type. See Remarks.

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Content encryption algorithm [default=Triple DES]. Deprecated: use contEncrAlg.

keyEncrAlg

:   Type: [Cms.KeyEncrAlgorithm](#T_Cms_KeyEncrAlgorithm)  

Key encryption algorithm for ktri type [default=RSAES-PKCS-v1_5)]

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash function for RSAES-OAEP or ECDH KDF or pwri PBKDF2, if required. Must be one of the SHA-* family [default=SHA-1]

advOptions

:   Type: [Cms.EnvDataOptions](#T_Cms_EnvDataOptions)  

Advanced options. See Cms.EnvDataOptions.

kdfAlg

:   Type: [Kdf.KdfAlg](#T_Kdf_KdfAlg)  

Key derivation function (KDF) for ECDH key agreement scheme (where applicable)

keyWrapAlg

:   Type: [Kdf.KeyWrapAlg](#T_Kdf_KeyWrapAlg)  

Key wrap algorithm for ECDH key agreement scheme or kekri type (default=match content encryption algorithm)

keyString

:   (formerly ukmString) Use to pass optional additional user key material (ukm) for KDF where KeyAgreement (kari) type is used. Or use to pass the password for a pwri type or the key encryption key (KEK) for a kekri type. Either pass a plain ASCII string, e.g. "abc" or use the format "#x<hex-digits>" to pass a string of arbitrary octet values, e.g. "#xdeadbeef01" to pass the 5 bytes 0xde,0xad,0xbe,0xef,0x01. Required for pwri and kekri types.

count

:   Optional iteration count for KDF in pwri type (default=4096) or tag length for AuthEnvelopedData (in range 12-16, default=16). Otherwise ignored.

contEncrAlg

:   Type: [Cms.ContentEncrAlg](#T_Cms_ContentEncrAlg)  

Alternative way to specify content encryption algorithm with more options. Takes precedence over cipherAlg.

#### Return Value

Number of successful recipients or a negative [error code](#errorcodes).

#### Remarks

The output is a file containing a CMS EnvelopedData object or AuthEnvelopedData object. *New in [v22.0]* use the preferred contEncrAlg parameter to specify the content-encryption algorithm rather than cipherAlg. If a list of certificates is passed in certList, the recipientInfo type is set automatically depending on the public key found in each certificate, one for each certificate. If the public key is RSA (rsaEncryption) then the key transport technique (ktri) will be used for that particular recipientInfo. If the public key is a supported ECC key, then the standard ECDH ephemeral-static key agreement technique (kari) will be used as per [RFC5753] and [RFC8418]. 

 If certList is set to "type=@pwri" then a single recipientInfo will be created of PasswordRecipientInfo type (pwri). The password must be passed in the keyString parameter. The parameters keyEncrAlg, kdfAlg and keyWrapAlg are ignored in this case. If certList is set to "type=@kekri,keyid=<string>" then a single recipientInfo will be created of KEKRecipientInfo type (kekri). The key encryption key (KEK) must be passed in the keyString parameter. The parameters keyEncrAlg, hashAlg and kdfAlg are ignored in this case.

#### Example

[`C#`]

```
// Create an enveloped CMS object (ktri type) to Bob using Bob's RSA key
n = Cms.MakeEnvData("cms2bob_aes128.p7m", "excontent.txt", "BobRSASignByCarl.cer", CipherAlgorithm.Aes128, Cms.KeyEncrAlgorithm.Rsa_Oaep);

// Create an enveloped CMS object (kekri type) using a previously distributed symmetric key-encryption key (KEK) 
n = Cms.MakeEnvData("cms_envdata_kekri.p7m", "excontent.txt", "type=@kekri,keyid=ourcommonkey", CipherAlgorithm.Aes256, 
        hashAlg: HashAlgorithm.Sha256, keyWrapAlg:Kdf.KeyWrapAlg.Aes128_wrap, keyString: "#x0123456789ABCDEFF0E1D2C3B4A59687");
```

#### See Also

VB6/C equivalent: [`CMS_MakeEnvData`](#CMS_MakeEnvData)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_MakeEnvDataFromBytes"></a>Cms.MakeEnvDataFromBytes Method

 Create a CMS enveloped-data object from data in a byte array. 

#### Syntax

[`C#`]

```
public static int MakeEnvDataFromBytes(
	string outputFile,
	byte[] inputData,
	string certList,
	CipherAlgorithm cipherAlg,
	Cms.KeyEncrAlgorithm keyEncrAlg,
	HashAlgorithm hashAlg,
	Cms.EnvDataOptions advOptions,
	Kdf.KdfAlg kdfAlg,
	Kdf.KeyWrapAlg keyWrapAlg,
	string keyString,
	int count,
	Cms.ContentEncrAlg contEncrAlg
)
```

[`VB.NET`]

```
Public Shared Function MakeEnvDataFromBytes ( _
	outputFile As String, _
	inputData As Byte(), _
	certList As String, _
	cipherAlg As CipherAlgorithm, _
	keyEncrAlg As Cms.KeyEncrAlgorithm, _
	hashAlg As HashAlgorithm, _
	advOptions As Cms.EnvDataOptions, _
	kdfAlg As Kdf.KdfAlg, _
	keyWrapAlg As Kdf.KeyWrapAlg, _
	keyString As String, _
	count As Integer, _
	contEncrAlg As Cms.ContentEncrAlg _
) As Integer
```

#### Parameters

outputFile

:   Output file to be created

inputData

:   Input data.

certList

:   List of one or more recipient X.509 certificate filenames, separated by semicolons (;). A certificate's representation in base64 or as a PEM string may be used instead of a filename. Alternatively, specify a single PKCS#7 certificate chain file (.p7c/.p7b). 

*Special cases:* Set as "type=@pwri" to create a single recipientInfo of the PasswordRecipientInfo (pwri) type; or set as "type=@kekri,keyid=<string>" to create a single recipientInfo of the KEKRecipientInfo (kekri) type. See Remarks.

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Content encryption algorithm [default=Triple DES]. Deprecated: use contEncrAlg.

keyEncrAlg

:   Type: [Cms.KeyEncrAlgorithm](#T_Cms_KeyEncrAlgorithm)  

Key encryption algorithm for ktri type [default=RSAES-PKCS-v1_5)]

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash function for RSAES-OAEP or ECDH KDF or pwri PBKDF2, if required. Must be one of the SHA-* family [default=SHA-1]

advOptions

:   Type: [Cms.EnvDataOptions](#T_Cms_EnvDataOptions)  

Advanced options. See Cms.EnvDataOptions.

kdfAlg

:   Type: [Kdf.KdfAlg](#T_Kdf_KdfAlg)  

Key derivation function (KDF) for ECDH key agreement scheme (where applicable)

keyWrapAlg

:   Type: [Kdf.KeyWrapAlg](#T_Kdf_KeyWrapAlg)  

Key wrap algorithm for ECDH key agreement scheme or kekri type (default=match content encryption algorithm)

keyString

:   (formerly ukmString) Use to pass optional additional user key material (ukm) for KDF where KeyAgreement (kari) type is used. Or use to pass the password for a pwri type or the key encryption key (KEK) for a kekri type. Either pass a plain ASCII string, e.g. "abc" or use the format "#x<hex-digits>" to pass a string of arbitrary octet values, e.g. "#xdeadbeef01" to pass the 5 bytes 0xde,0xad,0xbe,0xef,0x01. Required for pwri and kekri types.

count

:   Optional iteration count for KDF in pwri type (default=4096) or tag length for AuthEnvelopedData (in range 12-16, default=16). Otherwise ignored.

contEncrAlg

:   Type: [Cms.ContentEncrAlg](#T_Cms_ContentEncrAlg)  

Alternative way to specify content encryption algorithm with more options. Takes precedence over cipherAlg.

#### Return Value

Number of successful recipients or negative [error code](#errorcodes)

#### Remarks

See remarks for MakeEnvData(String, String, String, CipherAlgorithm, Cms.KeyEncrAlgorithm, HashAlgorithm, Cms.EnvDataOptions, Kdf.KdfAlg, Kdf.KeyWrapAlg, String, Int32, Cms.ContentEncrAlg)

#### See Also

VB6/C equivalent: [`CMS_MakeEnvDataFromBytes`](#CMS_MakeEnvDataFromBytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_MakeEnvDataFromString_StringStringStringCipherAlgorithmCms_EnvDataOptions"></a>Cms.MakeEnvDataFromString Method (String, String, String, CipherAlgorithm, Cms.EnvDataOptions)

 Create a CMS enveloped-data object from an ASCII string (default recipient parameters). 

#### Syntax

[`C#`]

```
public static int MakeEnvDataFromString(
	string outputFile,
	string inputData,
	string certList,
	CipherAlgorithm cipherAlg,
	Cms.EnvDataOptions advOptions
)
```

[`VB.NET`]

```
Public Shared Function MakeEnvDataFromString ( _
	outputFile As String, _
	inputData As String, _
	certList As String, _
	cipherAlg As CipherAlgorithm, _
	advOptions As Cms.EnvDataOptions _
) As Integer
```

#### Parameters

outputFile

:   Output file to be created

inputData

:   Input data string, expected plain ASCII text.

certList

:   List of recipient X.509 certificate filename(s), separated by semi-colons (;). Alternatively, specify a single PKCS#7 certificate chain file (.p7c/.p7b).

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Content encryption algorithm [default=Triple DES]

advOptions

:   Type: [Cms.EnvDataOptions](#T_Cms_EnvDataOptions)  

Advanced options. See Cms.EnvDataOptions.

#### Return Value

Number of successful recipients or negative [error code](#errorcodes)

#### See Also

VB6/C equivalent: [`CMS_MakeEnvDataFromString`](#CMS_MakeEnvDataFromString)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_MakeEnvDataFromString_StringStringStringCipherAlgorithmCms_KeyEncrAlgorithmHashAlgorithmCms_EnvDataOptionsKdf_KdfAlgKdf_KeyWrapAlgStringInt32Cms_ContentEncrAlg"></a>Cms.MakeEnvDataFromString Method (String, String, String, CipherAlgorithm, Cms.KeyEncrAlgorithm, HashAlgorithm, Cms.EnvDataOptions, Kdf.KdfAlg, Kdf.KeyWrapAlg, String, Int32, Cms.ContentEncrAlg)

 Create a CMS enveloped-data object from an ASCII string (advanced options). 

#### Syntax

[`C#`]

```
public static int MakeEnvDataFromString(
	string outputFile,
	string inputData,
	string certList,
	CipherAlgorithm cipherAlg,
	Cms.KeyEncrAlgorithm keyEncrAlg,
	HashAlgorithm hashAlg,
	Cms.EnvDataOptions advOptions,
	Kdf.KdfAlg kdfAlg,
	Kdf.KeyWrapAlg keyWrapAlg,
	string keyString,
	int count,
	Cms.ContentEncrAlg contEncrAlg
)
```

[`VB.NET`]

```
Public Shared Function MakeEnvDataFromString ( _
	outputFile As String, _
	inputData As String, _
	certList As String, _
	cipherAlg As CipherAlgorithm, _
	keyEncrAlg As Cms.KeyEncrAlgorithm, _
	hashAlg As HashAlgorithm, _
	advOptions As Cms.EnvDataOptions, _
	kdfAlg As Kdf.KdfAlg, _
	keyWrapAlg As Kdf.KeyWrapAlg, _
	keyString As String, _
	count As Integer, _
	contEncrAlg As Cms.ContentEncrAlg _
) As Integer
```

#### Parameters

outputFile

:   Output file to be created

inputData

:   Input data string, expected plain ASCII text.

certList

:   List of recipient X.509 certificate filename(s), separated by semi-colons (;). Alternatively, specify a single PKCS#7 certificate chain file (.p7c/.p7b). 

*Special cases:* Set as "type=@pwri" to create a single recipientInfo of the PasswordRecipientInfo type (pwri); or set as "type=@kekri,keyid=<string>" to create a single recipientInfo of the KEKRecipientInfo type (kekri). See Remarks.

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Content encryption algorithm [default=Triple DES]. Deprecated: use contEncrAlg.

keyEncrAlg

:   Type: [Cms.KeyEncrAlgorithm](#T_Cms_KeyEncrAlgorithm)  

Key encryption algorithm [default=rsaEncryption)]

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash function for RSAES-OAEP or ECDH KDF or PBKDF2 for pwri, if required. Must be one of the SHA-* family [default=SHA-1]

advOptions

:   Type: [Cms.EnvDataOptions](#T_Cms_EnvDataOptions)  

Advanced options. See Cms.EnvDataOptions.

kdfAlg

:   Type: [Kdf.KdfAlg](#T_Kdf_KdfAlg)  

Key derivation function (KDF) for ECDH key agreement scheme (where applicable)

keyWrapAlg

:   Type: [Kdf.KeyWrapAlg](#T_Kdf_KeyWrapAlg)  

Key wrap algorithm for ECDH key agreement scheme (default=match content encryption algorithm)

keyString

:   (formerly ukmString) Use to pass optional additional user key material (ukm) for KDF where KeyAgreement (kari) type is used. Or use to pass the password for a pwri type or the key encryption key (KEK) for a kekri type. Either pass a plain ASCII string, e.g. "abc" or use the format "#x<hex-digits>" to pass a string of arbitrary octet values, e.g. "#xdeadbeef01" to pass the 5 bytes 0xde,0xad,0xbe,0xef,0x01. Optional for kari types but required for pwri and kekri types.

count

:   Optional iteration count for KDF in pwri type (default=4096) or tag length for AuthEnvelopedData (in range 12-16, default=16). Otherwise ignored.

contEncrAlg

:   Type: [Cms.ContentEncrAlg](#T_Cms_ContentEncrAlg)  

Alternative way to specify content encryption algorithm with more options. Takes precedence over cipherAlg.

#### Return Value

Number of successful recipients or negative [error code](#errorcodes)

#### Remarks

See remarks for MakeEnvData(String, String, String, CipherAlgorithm, Cms.KeyEncrAlgorithm, HashAlgorithm, Cms.EnvDataOptions, Kdf.KdfAlg, Kdf.KeyWrapAlg, String, Int32, Cms.ContentEncrAlg)

#### See Also

VB6/C equivalent: [`CMS_MakeEnvDataFromString`](#CMS_MakeEnvDataFromString)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_MakeSigData_StringStringStringStringCms_SigAlgCms_SigDataOptions"></a>Cms.MakeSigData Method (String, String, String, String, Cms.SigAlg, Cms.SigDataOptions)

 Create a CMS object of type SignedData from an input data file (advanced options including RSA-PSS). 

#### Syntax

[`C#`]

```
public static int MakeSigData(
	string outputFile,
	string inputFile,
	string certList,
	string privateKey,
	Cms.SigAlg sigAlg,
	Cms.SigDataOptions advOptions
)
```

[`VB.NET`]

```
Public Shared Function MakeSigData ( _
	outputFile As String, _
	inputFile As String, _
	certList As String, _
	privateKey As String, _
	sigAlg As Cms.SigAlg, _
	advOptions As Cms.SigDataOptions _
) As Integer
```

#### Parameters

outputFile

:   name of output file to be created

inputFile

:   name of file containing message data to be signed

certList

:   filename of the signer's certificate and (optionally) a list of other certificates to be included in the output, separated by semi-colons (;) Alternatively specify a single PKCS#7 certificate chain file (.p7c/.p7b) containing the signer's certificate.

privateKey

:   private key data for the sender

sigAlg

:   Type: [Cms.SigAlg](#T_Cms_SigAlg)  

Signature algorithm.

advOptions

:   Type: [Cms.SigDataOptions](#T_Cms_SigDataOptions)  

Advanced option flags. See Cms.SigDataOptions.

#### Return Value

Zero if successful; otherwise it returns an [error code](#errorcodes)

#### Example

[`C#`]

```
StringBuilder sbPrivateKey = Rsa.ReadPrivateKey("AlicePrivRSASign.p8e", "password");
string fnameOutput = "BasicSignByAlice.bin";
string fnameInput = "excontent.txt";
string fnameCert = "AliceRSASignByCarl.cer";
int n = Cms.MakeSigData(fnameOutput, fnameInput, fnameCert, sbPrivateKey.ToString(), Cms.SigAlg.Default, 0);
```

#### See Also

VB6/C equivalent: [`CMS_MakeSigData`](#CMS_MakeSigData)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_MakeSigData_StringStringStringStringHashAlgorithmCms_SigDataOptions"></a>Cms.MakeSigData Method (String, String, String, String, HashAlgorithm, Cms.SigDataOptions)

 Create a CMS object of type SignedData from an input data file using RSASSA-PKCS1V1_5 with options. 

#### Syntax

[`C#`]

```
public static int MakeSigData(
	string outputFile,
	string inputFile,
	string certList,
	string privateKey,
	HashAlgorithm hashAlg,
	Cms.SigDataOptions advOptions
)
```

[`VB.NET`]

```
Public Shared Function MakeSigData ( _
	outputFile As String, _
	inputFile As String, _
	certList As String, _
	privateKey As String, _
	hashAlg As HashAlgorithm, _
	advOptions As Cms.SigDataOptions _
) As Integer
```

#### Parameters

outputFile

:   name of output file to be created

inputFile

:   name of file containing message data to be signed

certList

:   filename of the signer's certificate and (optionally) a list of other certificates to be included in the output, separated by semi-colons (;) Alternatively specify a single PKCS#7 certificate chain file (.p7c/.p7b) containing the signer's certificate.

privateKey

:   private key data for the sender

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Message digest algorithm to be used in signature [default=SHA-1].

advOptions

:   Type: [Cms.SigDataOptions](#T_Cms_SigDataOptions)  

Advanced option flags. See Cms.SigDataOptions.

#### Return Value

Zero if successful; otherwise it returns an [error code](#errorcodes)

#### Remarks

RSASSA-PKCS1V1_5 only.

#### See Also

VB6/C equivalent: [`CMS_MakeSigData`](#CMS_MakeSigData)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_MakeSigDataFromBytes"></a>Cms.MakeSigDataFromBytes Method

 Create a CMS object of type SignedData from an array of bytes. 

#### Syntax

[`C#`]

```
public static int MakeSigDataFromBytes(
	string outputFile,
	byte[] inputData,
	string certList,
	string privateKey,
	Cms.SigAlg sigAlg,
	Cms.SigDataOptions advOptions
)
```

[`VB.NET`]

```
Public Shared Function MakeSigDataFromBytes ( _
	outputFile As String, _
	inputData As Byte(), _
	certList As String, _
	privateKey As String, _
	sigAlg As Cms.SigAlg, _
	advOptions As Cms.SigDataOptions _
) As Integer
```

#### Parameters

outputFile

:   name of output file to be created.

inputData

:   message data to be signed in a byte array.

certList

:   filename of the signer's certificate and (optionally) a list of other certificates to be included in the output, separated by semi-colons (;) Alternatively specify a single PKCS#7 certificate chain file (.p7c/.p7b) containing the signer's certificate.

privateKey

:   Private key data for the sender.

sigAlg

:   Type: [Cms.SigAlg](#T_Cms_SigAlg)  

Signature algorithm.

advOptions

:   Type: [Cms.SigDataOptions](#T_Cms_SigDataOptions)  

Advanced option flags. See Cms.SigDataOptions.

#### Return Value

Zero if successful; otherwise it returns an [error code](#errorcodes)

#### See Also

VB6/C equivalent: [`CMS_MakeSigDataFromBytes`](#CMS_MakeSigDataFromBytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_MakeSigDataFromPseudo"></a>Cms.MakeSigDataFromPseudo Method

 Create a SignedData object from a "pseudo" object. 

#### Syntax

[`C#`]

```
public static int MakeSigDataFromPseudo(
	string outputFile,
	string inputPseudoFile,
	byte[] sigValue,
	Cms.Format format
)
```

[`VB.NET`]

```
Public Shared Function MakeSigDataFromPseudo ( _
	outputFile As String, _
	inputPseudoFile As String, _
	sigValue As Byte(), _
	format As Cms.Format _
) As Integer
```

#### Parameters

outputFile

:   Name of output file to be created.

inputPseudoFile

:   Input "pseudo" file with dummy placeholder signature.

sigValue

:   Signature value computed by external service.

format

:   Type: [Cms.Format](#T_Cms_Format)  

Output format (default = binary)

#### Return Value

Zero if successful; otherwise it returns an [error code](#errorcodes)

#### Remarks

RSASSA-PKCS1V1_5 only.

#### See Also

VB6/C equivalent: [`CMS_MakeSigDataFromSigValue`](#CMS_MakeSigDataFromSigValue)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_MakeSigDataFromSigValue"></a>Cms.MakeSigDataFromSigValue Method

 Create a CMS object of type SignedData using a pre-computed signature (advanced algorithms). 

#### Syntax

[`C#`]

```
public static int MakeSigDataFromSigValue(
	string outputFile,
	byte[] sigValue,
	byte[] contentData,
	string certList,
	HashAlgorithm hashAlg,
	Cms.SigDataOptions advOptions
)
```

[`VB.NET`]

```
Public Shared Function MakeSigDataFromSigValue ( _
	outputFile As String, _
	sigValue As Byte(), _
	contentData As Byte(), _
	certList As String, _
	hashAlg As HashAlgorithm, _
	advOptions As Cms.SigDataOptions _
) As Integer
```

#### Parameters

outputFile

:   name of output file to be created

sigValue

:   signature value

contentData

:   string containing content data that has been signed

certList

:   filename of the signer's certificate and (optionally) a list of other certificates to be included in the output, separated by semi-colons (;) Alternatively specify a single PKCS#7 certificate chain file (.p7c/.p7b) containing the signer's certificate.

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Message digest algorithm to be used in signature [default=SHA-1]

advOptions

:   Type: [Cms.SigDataOptions](#T_Cms_SigDataOptions)  

Advanced option flags. See Cms.SigDataOptions.

#### Return Value

Zero if successful; otherwise it returns an [error code](#errorcodes)

#### Remarks

RSASSA-PKCS1V1_5 only.

#### See Also

VB6/C equivalent: [`CMS_MakeSigDataFromSigValue`](#CMS_MakeSigDataFromSigValue)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_MakeSigDataFromString_StringStringStringStringCms_SigAlgCms_SigDataOptions"></a>Cms.MakeSigDataFromString Method (String, String, String, String, Cms.SigAlg, Cms.SigDataOptions)

 Create a CMS object of type SignedData from an input string (advanced options including RSA-PSS). 

#### Syntax

[`C#`]

```
public static int MakeSigDataFromString(
	string outputFile,
	string inputData,
	string certList,
	string privateKey,
	Cms.SigAlg sigAlg,
	Cms.SigDataOptions advOptions
)
```

[`VB.NET`]

```
Public Shared Function MakeSigDataFromString ( _
	outputFile As String, _
	inputData As String, _
	certList As String, _
	privateKey As String, _
	sigAlg As Cms.SigAlg, _
	advOptions As Cms.SigDataOptions _
) As Integer
```

#### Parameters

outputFile

:   name of output file to be created

inputData

:   string containing message data to be signed

certList

:   filename of the signer's certificate and (optionally) a list of other certificates to be included in the output, separated by semi-colons (;) Alternatively specify a single PKCS#7 certificate chain file (.p7c/.p7b) containing the signer's certificate.

privateKey

:   private key data for the sender

sigAlg

:   Type: [Cms.SigAlg](#T_Cms_SigAlg)  

Signature algorithm.

advOptions

:   Type: [Cms.SigDataOptions](#T_Cms_SigDataOptions)  

Advanced option flags. See Cms.SigDataOptions.

#### Return Value

Zero if successful; otherwise it returns an [error code](#errorcodes)

#### See Also

VB6/C equivalent: [`CMS_MakeSigDataFromString`](#CMS_MakeSigDataFromString)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_MakeSigDataFromString_StringStringStringStringHashAlgorithmCms_SigDataOptions"></a>Cms.MakeSigDataFromString Method (String, String, String, String, HashAlgorithm, Cms.SigDataOptions)

 Create a CMS object of type SignedData from an input string using RSASSA-PKCS1V1_5 with options. 

#### Syntax

[`C#`]

```
public static int MakeSigDataFromString(
	string outputFile,
	string inputData,
	string certList,
	string privateKey,
	HashAlgorithm hashAlg,
	Cms.SigDataOptions advOptions
)
```

[`VB.NET`]

```
Public Shared Function MakeSigDataFromString ( _
	outputFile As String, _
	inputData As String, _
	certList As String, _
	privateKey As String, _
	hashAlg As HashAlgorithm, _
	advOptions As Cms.SigDataOptions _
) As Integer
```

#### Parameters

outputFile

:   name of output file to be created

inputData

:   string containing message data to be signed

certList

:   filename of the signer's certificate and (optionally) a list of other certificates to be included in the output, separated by semi-colons (;) Alternatively specify a single PKCS#7 certificate chain file (.p7c/.p7b) containing the signer's certificate.

privateKey

:   private key data for the sender

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Message digest algorithm to be used in signature [default=SHA-1]

advOptions

:   Type: [Cms.SigDataOptions](#T_Cms_SigDataOptions)  

Advanced option flags. See Cms.SigDataOptions.

#### Return Value

Zero if successful; otherwise it returns an [error code](#errorcodes)

#### Remarks

RSASSA-PKCS1V1_5 only.

#### See Also

VB6/C equivalent: [`CMS_MakeSigDataFromString`](#CMS_MakeSigDataFromString)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_QueryEnvData"></a>Cms.QueryEnvData Method

 Query a CMS enveloped-data object file for selected information. 

#### Syntax

[`C#`]

```
public static string QueryEnvData(
	string inputFile,
	string query
)
```

[`VB.NET`]

```
Public Shared Function QueryEnvData ( _
	inputFile As String, _
	query As String _
) As String
```

#### Parameters

inputFile

:   file containing CMS enveloped-data object

query

:   Query string (case insensitive)

#### Return Value

String containing the result or an empty string if not found or error.

#### Remarks

Valid queries are:

 

| "version" | envelopedData CMSVersion (edVer) value, e.g. "0". |
| --- | --- |
| "recipientInfoVersion" | recipientInfo version (riVer) value. |
| "recipientInfoType" | Type of recipientInfo, e.g. ktri, kari, ... |
| "CountOfRecipientInfos" | Number of RecipientInfos included in the data. |
| "recipientIssuerName" | Distinguished Name of recipient's certificate issuer. |
| "recipientSerialNumber" | serialNumber of recipient's certificate in hex format |
| "keyEncryptionAlgorithm" | keyEncryptionAlgorithm, e.g. "rsaEncryption". |
| "keyEncryptionFlags" | Bit flags used for the key encryption algorithm (ktri only). |
| "SizeOfEncryptedKey" | Size (in bytes) of the EncryptedKey. |
| "encryptedKey" | EncryptedKey value encoded in hex. |
| "oaepParams" | Parameters used for RSA-OAEP (if applicable). |
| "keyWrapAlgorithm" | Key wrap algorithm, e.g. "aes128-wrap" (kari and kekri only). |
| "originatorKeyAlgorithm" | OriginatorPublicKey algorithm, e.g. "ecPublicKey" (kari only). |
| "originatorPublicKey" | OriginatorPublicKey publicKey value encoded in hex (kari only). |
| "keyid" | keyIdentifier for KEKRecipientInfo (kekri) type. |
| "contentEncryptionAlgorithm" | contentEncryptionAlgorithm, e.g. "des-EDE3-CBC". |
| "SizeOfEncryptedContent" | Size (in bytes) of the EncryptedContent. |
| "encryptedContent" | EncryptedContent encoded in hex. |
| "iv" | Initialization vector encoded in hex. |

 By default, the function queries the first recipientInfo in the file. To query the Nth recipientInfo append "/N" to the query string, e.g. "recipientInfoVersion/2" to find the version number of the second recipientInfo in the file.

#### See Also

VB6/C equivalent: [`CMS_QueryEnvData`](#CMS_QueryEnvData)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_QuerySigData"></a>Cms.QuerySigData Method

 Query a CMS signed-data object for selected information. 

#### Syntax

[`C#`]

```
public static string QuerySigData(
	string inputFile,
	string query
)
```

[`VB.NET`]

```
Public Shared Function QuerySigData ( _
	inputFile As String, _
	query As String _
) As String
```

#### Parameters

inputFile

:   file containing CMS signed-data object

query

:   Query string (case insensitive)

#### Return Value

String containing the result or an empty string if not found or error.

#### Remarks

Valid queries are:

 

| "version" | signedData version (sdVer) value, e.g. "1". |
| --- | --- |
| "eContentType" | ContentType of the EncapsulatedContentInfo, e.g. "data". |
| "HASeContent" | "1" if eContent is present; "0" if not. |
| "CountOfCertificates" | Number of certificates included in the data. |
| "CountOfSignerInfos" | Number of SignerInfos included in the data. |
| "signerInfoVersion" | signerInfo version (siVer) value. |
| "digestAlgorithm" | digestAlgorithm, e.g. "sha1". |
| "signatureAlgorithm" | signatureAlgorithm, e.g. "rsaEncryption". |
| "signatureValue" | Signature value encoded in hex. |
| "HASsignedAttributes" | "1" if signedAttributes (authenticatedAttributes) are present; "0" if not. |
| "DigestOfSignedAttrs" | Computed digest over signed attributes, if present, using digestAlgorithm. |
| "DigestOfeContent" | Computed digest over eContent, if present, using digestAlgorithm. |
| "signingTime" | signingTime attribute in format "2005-12-31 23:30:59" |
| "messageDigest" | messageDigest attribute in hexadecimal format, if present |
| "pssParams" | Parameters used for RSA-PSS (if applicable). |
| "HASsigningCertificate" | "1" if an ESS signingCertificate is present; "0" if not. |
| "signingCertHash" | certHash value of ESS signing certificate, if present, encoded in hex. |
| "HASalgorithmProtection" | "1" if a cmsAlgorithmProtection attribute is present; "0" if not. |

 By default, the function queries the first signerInfo in the file. To query the Nth signerInfo append "/N" to the query string, e.g. "signerInfoVersion/2" to find the version number of the second signerInfo in the file.

#### See Also

VB6/C equivalent: [`CMS_QuerySigData`](#CMS_QuerySigData)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_ReadComprData"></a>Cms.ReadComprData Method

 Read and extract the decompressed contents of a CMS compressed-data file. 

#### Syntax

[`C#`]

```
public static int ReadComprData(
	string outputFile,
	string inputFile,
	Cms.ComprDataOptions opts
)
```

[`VB.NET`]

```
Public Shared Function ReadComprData ( _
	outputFile As String, _
	inputFile As String, _
	opts As Cms.ComprDataOptions _
) As Integer
```

#### Parameters

outputFile

:   Output file to be created

inputFile

:   Input data file

opts

:   Type: [Cms.ComprDataOptions](#T_Cms_ComprDataOptions)  

Options [default=inflate contents]

#### Return Value

If successful the return value is the number of bytes in the output file; otherwise it returns a non-zero [error code](#errorcodes)

#### See Also

VB6/C equivalent: [`CMS_ReadComprData`](#CMS_ReadComprData)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_ReadEnvDataToBytes"></a>Cms.ReadEnvDataToBytes Method

 Read and decrypt a CMS enveloped-data object to a byte array. 

#### Syntax

[`C#`]

```
public static byte[] ReadEnvDataToBytes(
	string inputFile,
	string x509File,
	string privateKey
)
```

[`VB.NET`]

```
Public Shared Function ReadEnvDataToBytes ( _
	inputFile As String, _
	x509File As String, _
	privateKey As String _
) As Byte()
```

#### Parameters

inputFile

:   Name of file containing CMS enveloped-data object (binary or base64-encoded) or the data as a base64 or PEM string.

x509File

:   (optional) filename of the recipient's X.509 certificate.

privateKey

:   Internal representation of private key.

#### Return Value

Decrypted content in a byte array, or empty array on error.

#### Example

[`C#`]

```
// Read in content to a byte array
byte[] b = Cms.ReadEnvDataToBytes(inputFile, "", privateKey);
// Convert to a .NET string (assuming UTF-8 encoded)
string s = System.Text.Encoding.UTF8.GetString(b);
```

#### See Also

VB6/C equivalent: [`CMS_ReadEnvDataToBytes`](#CMS_ReadEnvDataToBytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_ReadEnvDataToFile"></a>Cms.ReadEnvDataToFile Method

 Read and decrypt a CMS enveloped-data object to a file. 

#### Syntax

[`C#`]

```
public static int ReadEnvDataToFile(
	string outputFile,
	string inputFile,
	string x509File,
	string privateKey,
	Cms.ReadOptions opts
)
```

[`VB.NET`]

```
Public Shared Function ReadEnvDataToFile ( _
	outputFile As String, _
	inputFile As String, _
	x509File As String, _
	privateKey As String, _
	opts As Cms.ReadOptions _
) As Integer
```

#### Parameters

outputFile

:   Name of output file to be created.

inputFile

:   Name of file containing CMS enveloped-data object (binary or base64-encoded) or the data as a base64 or PEM string.

x509File

:   (optional) filename of the recipient's X.509 certificate.

privateKey

:   Internal representation of private key.

opts

:   Type: [Cms.ReadOptions](#T_Cms_ReadOptions)  

Use Cms.ReadOptions for faster handling of large files (binary only).

#### Return Value

Zero if successful; otherwise it returns an [error code](#errorcodes).

#### See Also

VB6/C equivalent: [`CMS_ReadEnvData`](#CMS_ReadEnvData)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_ReadEnvDataToString"></a>Cms.ReadEnvDataToString Method

 Read and decrypt a CMS enveloped-data object to a string. 

#### Syntax

[`C#`]

```
public static string ReadEnvDataToString(
	string inputFile,
	string x509File,
	string privateKey
)
```

[`VB.NET`]

```
Public Shared Function ReadEnvDataToString ( _
	inputFile As String, _
	x509File As String, _
	privateKey As String _
) As String
```

#### Parameters

inputFile

:   Name of file containing CMS enveloped-data object (binary or base64-encoded) or the data as a base64 or PEM string.

x509File

:   (optional) filename of the recipient's X.509 certificate

privateKey

:   Internal representation of private key.

#### Return Value

Decrypted content in a string or empty string on error.

#### Remarks

Use this only when the decrypted text is known to be plain ASCII text, otherwise use ReadEnvDataToBytes.

#### See Also

VB6/C equivalent: [`CMS_ReadEnvDataToString`](#CMS_ReadEnvDataToString)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_ReadSigDataToBytes"></a>Cms.ReadSigDataToBytes Method

 Read the content from a CMS signed-data object directly into a byte array. 

#### Syntax

[`C#`]

```
public static byte[] ReadSigDataToBytes(
	string inputFile
)
```

[`VB.NET`]

```
Public Shared Function ReadSigDataToBytes ( _
	inputFile As String _
) As Byte()
```

#### Parameters

inputFile

:   Name of file containing CMS signed-data object (binary or base64-encoded) or the data as a base64 or PEM string.

#### Return Value

Byte array containing the content or a zero-length array if error.

#### Remarks

Use this if the content contains non-ASCII characters, e.g. UTF-8 encoded.

#### Example

[`C#`]

```
// Read in content to a byte array
byte[] b = Cms.ReadSigDataToBytes(inputFile);
// Convert to a .NET string (assumed UTF-8 encoded)
string s = System.Text.Encoding.UTF8.GetString(b);
```

#### See Also

VB6/C equivalent: [`CMS_ReadSigDataToBytes`](#CMS_ReadSigDataToBytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_ReadSigDataToFile"></a>Cms.ReadSigDataToFile Method

 Read the content from a CMS signed-data object file. 

#### Syntax

[`C#`]

```
public static int ReadSigDataToFile(
	string outputFile,
	string inputFile,
	Cms.ReadOptions opts
)
```

[`VB.NET`]

```
Public Shared Function ReadSigDataToFile ( _
	outputFile As String, _
	inputFile As String, _
	opts As Cms.ReadOptions _
) As Integer
```

#### Parameters

outputFile

:   file to receive content

inputFile

:   Name of file containing CMS signed-data object (binary or base64-encoded) or the data as a base64 or PEM string.

opts

:   Type: [Cms.ReadOptions](#T_Cms_ReadOptions)  

Option flags: set as zero for defaults.

#### Return Value

If successful, the return value is a positive number indicating the number of bytes in the content; otherwise it returns a negative [error code](#errorcodes).

#### See Also

VB6/C equivalent: [`CMS_ReadSigData`](#CMS_ReadSigData)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_ReadSigDataToString"></a>Cms.ReadSigDataToString Method

 Read the content from a CMS signed-data object directly into a string. 

#### Syntax

[`C#`]

```
public static string ReadSigDataToString(
	string inputFile
)
```

[`VB.NET`]

```
Public Shared Function ReadSigDataToString ( _
	inputFile As String _
) As String
```

#### Parameters

inputFile

:   Name of file containing CMS signed-data object (binary or base64-encoded) or the data as a base64 or PEM string.

#### Return Value

String containing the content or an empty string if error

#### See Also

VB6/C equivalent: [`CMS_ReadSigDataToString`](#CMS_ReadSigDataToString)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cms_VerifySigData"></a>Cms.VerifySigData Method

 Verify the signature and content of a signed-data CMS object file. 

#### Syntax

[`C#`]

```
public static int VerifySigData(
	string inputFile,
	string certFile,
	string hexDigest,
	Cms.SigDataOptions advOptions
)
```

[`VB.NET`]

```
Public Shared Function VerifySigData ( _
	inputFile As String, _
	certFile As String, _
	hexDigest As String, _
	advOptions As Cms.SigDataOptions _
) As Integer
```

#### Parameters

inputFile

:   file containing CMS signed-data object

certFile

:   an (optional) X.509 certificate file of the signer

hexDigest

:   (optional) digest of eContent to be verified (use for "detached-signature" form)

advOptions

:   Type: [Cms.SigDataOptions](#T_Cms_SigDataOptions)  

Use for BigFile option, otherwise ignored

#### Return Value

Zero if successfully verified; otherwise it returns a non-zero [error code](#errorcodes)

#### See Also

VB6/C equivalent: [`CMS_VerifySigData`](#CMS_VerifySigData)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_Base64Filter"></a>Cnv.Base64Filter Method

 Filter non-base64 characters from a string. 

#### Syntax

[`C#`]

```
public static string Base64Filter(
	string s
)
```

[`VB.NET`]

```
Public Shared Function Base64Filter ( _
	s As String _
) As String
```

#### Parameters

s

:   String to be filtered

#### Return Value

Filtered string

#### Remarks

Valid base64 characters are [0-9A-Za-z+/=]

#### See Also

VB6/C equivalent: [`CNV_B64Filter`](#CNV_B64Filter)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_Base64FromHex"></a>Cnv.Base64FromHex Method

 Convert hexadecimal-encoded data into base64-encoded data. 

#### Syntax

[`C#`]

```
public static string Base64FromHex(
	string s
)
```

[`VB.NET`]

```
Public Shared Function Base64FromHex ( _
	s As String _
) As String
```

#### Parameters

s

:   Hex-encoded data

#### Return Value

Base64-encoded data

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_ByteEncoding"></a>Cnv.ByteEncoding Method

 Convert encoding of byte array between UTF-8 and Latin-1. 

#### Syntax

[`C#`]

```
public static byte[] ByteEncoding(
	byte[] data,
	Cnv.EncodingConversion direction
)
```

[`VB.NET`]

```
Public Shared Function ByteEncoding ( _
	data As Byte(), _
	direction As Cnv.EncodingConversion _
) As Byte()
```

#### Parameters

data

:   Input data to be converted

direction

:   Type: [Cnv.EncodingConversion](#T_Cnv_EncodingConversion)  

Direction of conversion

#### Return Value

Converted data (or empty array on error)

#### Remarks

Converting UTF-8 from Latin-1 assumes the input is from the 8-bit Latin-1 character set and so will *always* produce output that is valid UTF-8. However, for Latin-1 from UTF-8, the input *must* contain a valid sequence of UTF-8-encoded bytes and this must be convertible to a single-byte character set, or an error will be returned.

#### See Also

VB6/C equivalent: [`CNV_ByteEncoding`](#CNV_ByteEncoding)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_CheckUTF8"></a>Cnv.CheckUTF8 Method

 Check that a byte array contains only valid UTF-8 encoded characters. 

#### Syntax

[`C#`]

```
public static int CheckUTF8(
	byte[] b
)
```

[`VB.NET`]

```
Public Shared Function CheckUTF8 ( _
	b As Byte() _
) As Integer
```

#### Parameters

b

:   input byte array to check

#### Return Value

Zero if the encoded bytes is invalid UTF-8, or a positive number if the input contains valid UTF-8 data, where the value of the number indicates the nature of the encoded characters: 

 

| 0 | Not valid UTF-8 |
| --- | --- |
| 1 | Valid UTF-8, all chars are 7-bit ASCII |
| 2 | Valid UTF-8, contains at least one multi-byte character equivalent to 8-bit ANSI |
| 3 | Valid UTF-8, contains at least one multi-byte character that cannot be represented in a single-byte character set |

#### Remarks

'Overlong' UTF-8 sequences and illegal surrogates are rejected as invalid.

#### See Also

VB6/C equivalent: [`CNV_CheckUTF8Bytes`](#CNV_CheckUTF8Bytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_CheckUTF8File"></a>Cnv.CheckUTF8File Method

 Check that a file contains only valid UTF-8 encoded characters. 

#### Syntax

[`C#`]

```
public static int CheckUTF8File(
	string fileName
)
```

[`VB.NET`]

```
Public Shared Function CheckUTF8File ( _
	fileName As String _
) As Integer
```

#### Parameters

fileName

:   name of file to check

#### Return Value

Zero if the encoded bytes is invalid UTF-8, or a positive number if the input contains valid UTF-8 data, where the value of the number indicates the nature of the encoded characters: 

 

| 0 | Not valid UTF-8 |
| --- | --- |
| 1 | Valid UTF-8, all chars are 7-bit ASCII |
| 2 | Valid UTF-8, contains at least one multi-byte character equivalent to 8-bit ANSI |
| 3 | Valid UTF-8, contains at least one multi-byte character that cannot be represented in a single-byte character set |

#### Remarks

'Overlong' UTF-8 sequences and illegal surrogates are rejected as invalid.

#### See Also

VB6/C equivalent: [`CNV_CheckUTF8File`](#CNV_CheckUTF8File)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_FromBase58"></a>Cnv.FromBase58 Method

 Convert a base58-encoded string to an equivalent array of 8-bit unsigned integers. 

#### Syntax

[`C#`]

```
public static byte[] FromBase58(
	string s
)
```

[`VB.NET`]

```
Public Shared Function FromBase58 ( _
	s As String _
) As Byte()
```

#### Parameters

s

:   Base58-encoded data

#### Return Value

Data as array of bytes

#### Remarks

This uses the "Bitcoin" scheme of base58 encoding where the leading character '1' is reserved for representing an entire leading zero byte.

#### See Also

VB6/C equivalent: [`CNV_Base58ToBytes`](#CNV_Base58ToBytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_FromBase64"></a>Cnv.FromBase64 Method

 Convert a base64-encoded string to an equivalent array of 8-bit unsigned integers. 

#### Syntax

[`C#`]

```
public static byte[] FromBase64(
	string s
)
```

[`VB.NET`]

```
Public Shared Function FromBase64 ( _
	s As String _
) As Byte()
```

#### Parameters

s

:   Base64-encoded data

#### Return Value

Binary data in byte array, or an empty array on error.

#### Remarks

Whitespace characters are ignored, but other non-base64 characters will cause an error.

#### See Also

VB6/C equivalent: [`CNV_BytesFromB64Str`](#CNV_BytesFromB64Str)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_FromHex"></a>Cnv.FromHex Method

 Convert the specified string representation of a value consisting of hexadecimal (base 16) digits to an equivalent array of 8-bit unsigned integers. 

#### Syntax

[`C#`]

```
public static byte[] FromHex(
	string s
)
```

[`VB.NET`]

```
Public Shared Function FromHex ( _
	s As String _
) As Byte()
```

#### Parameters

s

:   Hex-encoded string

#### Return Value

Binary data in byte array, or an empty array on error.

#### Remarks

Whitespace and ASCII punctuation characters are ignored, but other non-hex characters will cause an error.

#### See Also

VB6/C equivalent: [`CNV_BytesFromHexStr`](#CNV_BytesFromHexStr)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_HexFilter"></a>Cnv.HexFilter Method

 Filter non-hexadecimal characters from a string. 

#### Syntax

[`C#`]

```
public static string HexFilter(
	string s
)
```

[`VB.NET`]

```
Public Shared Function HexFilter ( _
	s As String _
) As String
```

#### Parameters

s

:   Input string to be filtered

#### Return Value

Filtered string

#### See Also

VB6/C equivalent: [`CNV_HexFilter`](#CNV_HexFilter)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_HexFromBase64"></a>Cnv.HexFromBase64 Method

 Convert base64-encoded data into hexadecimal-encoded data. 

#### Syntax

[`C#`]

```
public static string HexFromBase64(
	string s
)
```

[`VB.NET`]

```
Public Shared Function HexFromBase64 ( _
	s As String _
) As String
```

#### Parameters

s

:   Base64-encoded data

#### Return Value

Hex-encoded data

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_NumFromBytes"></a>Cnv.NumFromBytes Method

 Convert the leftmost four bytes of an array to an unsigned 32-bit integer. 

#### Syntax

[`C#`]

```
public static uint NumFromBytes(
	byte[] b,
	Cnv.EndianNess endn
)
```

[`VB.NET`]

```
Public Shared Function NumFromBytes ( _
	b As Byte(), _
	endn As Cnv.EndianNess _
) As UInteger
```

#### Parameters

b

:   Byte array to be converted

endn

:   Type: [Cnv.EndianNess](#T_Cnv_EndianNess)  

Byte order

#### Return Value

Integer value

#### Remarks

An array shorter than 4 bytes will be padded on the right with zeros

#### Example

[`C#`]

```
byte[] b = new byte[4] { 0xde, 0xad, 0xbe, 0xef };
uint nb = Cnv.NumFromBytes(b, Cnv.EndianNess.BigEndian);
Console.WriteLine("0x" + nb.ToString("x8"));  // 0xdeadbeef
uint nl = Cnv.NumFromBytes(b, Cnv.EndianNess.LittleEndian);
Console.WriteLine("0x" + nl.ToString("x8"));  // 0xefbeadde
```

#### See Also

VB6/C equivalent: [`CNV_NumFromBytes`](#CNV_NumFromBytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_NumToBytes"></a>Cnv.NumToBytes Method

 Convert a 32-bit integer to an array of 4 bytes. 

#### Syntax

[`C#`]

```
public static byte[] NumToBytes(
	uint n,
	Cnv.EndianNess endn
)
```

[`VB.NET`]

```
Public Shared Function NumToBytes ( _
	n As UInteger, _
	endn As Cnv.EndianNess _
) As Byte()
```

#### Parameters

n

:   Integer to be converted

endn

:   Type: [Cnv.EndianNess](#T_Cnv_EndianNess)  

Byte order

#### Return Value

Byte array containing representation of integer in given order

#### Example

[`C#`]

```
byte[] bb = Cnv.NumToBytes(0xdeadbeef, Cnv.EndianNess.BigEndian);
Console.WriteLine(Cnv.ToHex(bb));  // DEADBEEF
byte[] bl = Cnv.NumToBytes(0xdeadbeef, Cnv.EndianNess.LittleEndian);
Console.WriteLine(Cnv.ToHex(bl));  // EFBEADDE
```

#### See Also

VB6/C equivalent: [`CNV_NumToBytes`](#CNV_NumToBytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_ReverseBytes"></a>Cnv.ReverseBytes Method

 Reverse the order of a byte array. 

#### Syntax

[`C#`]

```
public static byte[] ReverseBytes(
	byte[] data
)
```

[`VB.NET`]

```
Public Shared Function ReverseBytes ( _
	data As Byte() _
) As Byte()
```

#### Parameters

data

:   Input data to be reversed

#### Return Value

Byte array in reverse order

#### See Also

VB6/C equivalent: [`CNV_ReverseBytes`](#CNV_ReverseBytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_ShortPathName"></a>Cnv.ShortPathName Method

 Retrieve the Windows short path form of the specified path. 

#### Syntax

[`C#`]

```
public static string ShortPathName(
	string pathName
)
```

[`VB.NET`]

```
Public Shared Function ShortPathName ( _
	pathName As String _
) As String
```

#### Parameters

pathName

:   File path name.

#### Return Value

Windows short path name of file or the empty string if file does not exist.

#### Remarks

Windows platforms only. The file path must exist. The short path name is guaranteed to be ASCII.

#### See Also

VB6/C equivalent: [`CNV_ShortPathName`](#CNV_ShortPathName)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_StringFromBase64"></a>Cnv.StringFromBase64 Method

 Convert a base64-encoded string into a text string. 

#### Syntax

[`C#`]

```
public static string StringFromBase64(
	string s
)
```

[`VB.NET`]

```
Public Shared Function StringFromBase64 ( _
	s As String _
) As String
```

#### Parameters

s

:   Base64-encoded data

#### Return Value

String value

#### Remarks

Uses the 'Default' encoding for the system's current ANSI code page. This assumes the user knows the resulting characters are all printable.

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_StringFromHex"></a>Cnv.StringFromHex Method

 Convert a hexadecimal-encoded string into a text string. 

#### Syntax

[`C#`]

```
public static string StringFromHex(
	string s
)
```

[`VB.NET`]

```
Public Shared Function StringFromHex ( _
	s As String _
) As String
```

#### Parameters

s

:   Hex-encoded data

#### Return Value

String value

#### Remarks

Uses the 'Default' encoding for the system's current ANSI code page, usually code page 1252 (similar to Latin-1). This assumes the user knows the resulting characters are all printable.

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_ToBase58"></a>Cnv.ToBase58 Method

 Convert 8-bit binary data to equivalent base58-encoded string format. 

#### Syntax

[`C#`]

```
public static string ToBase58(
	byte[] binaryData
)
```

[`VB.NET`]

```
Public Shared Function ToBase58 ( _
	binaryData As Byte() _
) As String
```

#### Parameters

binaryData

:   binary data

#### Return Value

Base58-encoded string

#### Remarks

This uses the "Bitcoin" scheme of base58 encoding where the leading character '1' is reserved for representing an entire leading zero byte.

#### See Also

VB6/C equivalent: [`CNV_Base58FromBytes`](#CNV_Base58FromBytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_ToBase64_Byte"></a>Cnv.ToBase64 Method (Byte[])

 Convert 8-bit binary data to equivalent base64-encoded string format. 

#### Syntax

[`C#`]

```
public static string ToBase64(
	byte[] binaryData
)
```

[`VB.NET`]

```
Public Shared Function ToBase64 ( _
	binaryData As Byte() _
) As String
```

#### Parameters

binaryData

:   binary data

#### Return Value

Base64-encoded string

#### See Also

VB6/C equivalent: [`CNV_B64StrFromBytes`](#CNV_B64StrFromBytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_ToBase64_String"></a>Cnv.ToBase64 Method (String)

 Convert a string of ANSI characters to equivalent base64-encoded string format. 

#### Syntax

[`C#`]

```
public static string ToBase64(
	string s
)
```

[`VB.NET`]

```
Public Shared Function ToBase64 ( _
	s As String _
) As String
```

#### Parameters

s

:   String of data to be encoded

#### Return Value

Base64-encoded data

#### Remarks

Uses the 'Default' encoding for the system's current ANSI code page

#### See Also

VB6/C equivalent: [`CNV_B64StrFromBytes`](#CNV_B64StrFromBytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_ToHex_Byte"></a>Cnv.ToHex Method (Byte[])

 Convert 8-bit binary data to equivalent hexadecimal string format. 

#### Syntax

[`C#`]

```
public static string ToHex(
	byte[] binaryData
)
```

[`VB.NET`]

```
Public Shared Function ToHex ( _
	binaryData As Byte() _
) As String
```

#### Parameters

binaryData

:   binary data in byte array

#### Return Value

Hex-encoded string.

#### See Also

VB6/C equivalent: [`CNV_HexStrFromBytes`](#CNV_HexStrFromBytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Cnv_ToHex_String"></a>Cnv.ToHex Method (String)

 Converts a string of ANSI characters to equivalent hexadecimal string format 

#### Syntax

[`C#`]

```
public static string ToHex(
	string s
)
```

[`VB.NET`]

```
Public Shared Function ToHex ( _
	s As String _
) As String
```

#### Parameters

s

:   String of data to be encoded

#### Return Value

Hex-encoded data

#### Remarks

Uses the 'Default' encoding for the system's current ANSI code page

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Compr_Compress"></a>Compr.Compress Method

 Compress data using zlib compression. 

#### Syntax

[`C#`]

```
public static byte[] Compress(
	byte[] data
)
```

[`VB.NET`]

```
Public Shared Function Compress ( _
	data As Byte() _
) As Byte()
```

#### Parameters

data

:   Data to be compressed.

#### Return Value

Compressed data, or an empty array on error.

#### See Also

VB6/C equivalent: [`COMPR_Compress`](#COMPR_Compress)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Compr_Uncompress"></a>Compr.Uncompress Method

 Uncompress data using zlib compression. 

#### Syntax

[`C#`]

```
public static byte[] Uncompress(
	byte[] data
)
```

[`VB.NET`]

```
Public Shared Function Uncompress ( _
	data As Byte() _
) As Byte()
```

#### Parameters

data

:   Compressed data to be uncompressed.

#### Return Value

Uncompressed data, or an empty array on error.

#### Remarks

An empty array may also be returned if the original data was the empty array itself.

#### See Also

VB6/C equivalent: [`COMPR_Uncompress`](#COMPR_Uncompress)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Ecc_DHSharedSecret"></a>Ecc.DHSharedSecret Method

 Compute EC Diffie-Hellman (ECDH) shared secret. 

#### Syntax

[`C#`]

```
public static byte[] DHSharedSecret(
	string ourIntPrivateKey,
	string theirIntPublicKey
)
```

[`VB.NET`]

```
Public Shared Function DHSharedSecret ( _
	ourIntPrivateKey As String, _
	theirIntPublicKey As String _
) As Byte()
```

#### Parameters

ourIntPrivateKey

:   Our own private key in ephemeral "internal" form.

theirIntPublicKey

:   Other party's public key in "internal" form.

#### Return Value

The Diffie-Hellman shared secret.

#### See Also

VB6/C equivalent: [`ECC_DHSharedSecret`](#ECC_DHSharedSecret)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Ecc_KeyHashCode"></a>Ecc.KeyHashCode Method

 Compute the hash code of an "internal" ECC public or private key string. 

#### Syntax

[`C#`]

```
public static int KeyHashCode(
	string intKeyString
)
```

[`VB.NET`]

```
Public Shared Function KeyHashCode ( _
	intKeyString As String _
) As Integer
```

#### Parameters

intKeyString

:   Internal key string

#### Return Value

A 32-bit hash code for the key, or zero on error.

#### Remarks

Should be the same for a matching private and public key.

#### See Also

VB6/C equivalent: [`ECC_KeyHashCode`](#ECC_KeyHashCode)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Ecc_MakeKeys"></a>Ecc.MakeKeys Method

 Generate an EC public/private key pair and save as two key files. 

#### Syntax

[`C#`]

```
public static int MakeKeys(
	string publicKeyfile,
	string privateKeyFile,
	Ecc.CurveName curveName,
	string password,
	Ecc.PbeScheme pbes,
	string paramString,
	Ecc.Format fileFormat
)
```

[`VB.NET`]

```
Public Shared Function MakeKeys ( _
	publicKeyfile As String, _
	privateKeyFile As String, _
	curveName As Ecc.CurveName, _
	password As String, _
	pbes As Ecc.PbeScheme, _
	paramString As String, _
	fileFormat As Ecc.Format _
) As Integer
```

#### Parameters

publicKeyfile

:   name of public key file to be created

privateKeyFile

:   name of encrypted private key file to be created

curveName

:   Type: [Ecc.CurveName](#T_Ecc_CurveName)  

name of elliptic curve

password

:   password to be used for the encrypted key file.

pbes

:   Type: [Ecc.PbeScheme](#T_Ecc_PbeScheme)  

(optional) Password-based encryption scheme to encrypt private key [default = pbeWithSHAAnd3-KeyTripleDES-CBC]

paramString

:   Optional parameters. A set of attribute name=value pairs separated by a semicolon ";" (see remarks).

fileFormat

:   Type: [Ecc.Format](#T_Ecc_Format)  

(optional) Format to save file [default = DER binary]

#### Return Value

Zero if successful or non-zero [error code](#errorcodes)

#### Remarks

Valid name-value pairs for paramString are:

 

| **count**=integer | To set the iteration count used in the PBKDF2 method, e.g. "count=5000;" [default=2048]. |
| --- | --- |
| **prf**=hmac-name | To change the HMAC algorithm used in the PBKDF2 method, e.g. "prf=hmacwithSHA256;" [default=hmacwithSHA1]. |
| **rngseed**=string | To add some user-supplied entropy for the key generation process, e.g. "rngseed=pqrrr1234xyz;". |

 Valid values for hmac-name are {hmacWithSHA1|hmacWithSHA224|hmacWithSHA256|hmacWithSHA384|hmacWithSHA512}.

#### Example

[`C#`]

```
// All default settings...
n = Ecc.MakeKeys(pubkeyfile, prikeyfile, Ecc.CurveName.Prime192v1, "password");
// With specialist options...
n = Ecc.MakeKeys(pubkeyfile, prikeyfile, Ecc.CurveName.Prime192v1, "password", 
       Ecc.PbeScheme.Pbe_Pbkdf2_aes128_CBC, "count=3999;prf=hmacWithSha256", Ecc.Format.PEM);
```

#### See Also

VB6/C equivalent: [`ECC_MakeKeys`](#ECC_MakeKeys)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Ecc_PublicKeyFromPrivate"></a>Ecc.PublicKeyFromPrivate Method

 Convert an internal EC private key string into an internal EC public key string. 

#### Syntax

[`C#`]

```
public static string PublicKeyFromPrivate(
	string internalKey
)
```

[`VB.NET`]

```
Public Shared Function PublicKeyFromPrivate ( _
	internalKey As String _
) As String
```

#### Parameters

internalKey

:   the private key as an internal key string

#### Return Value

The public key in ephemeral "internal" representation, or the empty string on error

#### See Also

VB6/C equivalent: [`ECC_PublicKeyFromPrivate`](#ECC_PublicKeyFromPrivate)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Ecc_QueryKey"></a>Ecc.QueryKey Method

 Query an EC key string for selected information. 

#### Syntax

[`C#`]

```
public static string QueryKey(
	string internalKey,
	string query
)
```

[`VB.NET`]

```
Public Shared Function QueryKey ( _
	internalKey As String, _
	query As String _
) As String
```

#### Parameters

internalKey

:   containing the key as an internal key string

query

:   Query string (case insensitive)

#### Return Value

String containing the result or an empty string if not found or error.

#### Remarks

Valid queries are:

 

| "curveName" | Name of the curve. |
| --- | --- |
| "keyBits" | Number of bits in the key. |
| "isPrivate" | "1" if key is a private key; "0" if not. |
| "privateKey" | Value of the private key in hex format. |
| "publicKey" | Value of the public key in hex format. |

#### See Also

VB6/C equivalent: [`ECC_QueryKey`](#ECC_QueryKey)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Ecc_ReadKeyByCurve"></a>Ecc.ReadKeyByCurve Method

 Read an EC key from its hexadecimal representation with options for safe curves. 

#### Syntax

[`C#`]

```
public static string ReadKeyByCurve(
	string hexKey,
	Ecc.CurveName curveName,
	Ecc.KeyType keyType
)
```

[`VB.NET`]

```
Public Shared Function ReadKeyByCurve ( _
	hexKey As String, _
	curveName As Ecc.CurveName, _
	keyType As Ecc.KeyType _
) As String
```

#### Parameters

hexKey

:   hexadecimal representation of the key, private or public

curveName

:   Type: [Ecc.CurveName](#T_Ecc_CurveName)  

name of the elliptic curve

keyType

:   Type: [Ecc.KeyType](#T_Ecc_KeyType)  

(optional) Specify PrivateKey or PublicKey (safe curves Ed25519 and X25519 only, otherwise ignored)

#### Return Value

The key in ephemeral "internal" representation, or the empty string on error

#### Remarks

The safe curves Ed25519 and X25519 have the same length for both private and public keys, so, for these safe curves, you **must** specify whether the key value represents a public or a private key.

#### See Also

VB6/C equivalent: [`ECC_ReadKeyByCurve`](#ECC_ReadKeyByCurve)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Ecc_ReadPrivateKey"></a>Ecc.ReadPrivateKey Method

 Read from a file or string containing an EC private key into an "internal" private key string. 

#### Syntax

[`C#`]

```
public static StringBuilder ReadPrivateKey(
	string keyFileOrString,
	string password
)
```

[`VB.NET`]

```
Public Shared Function ReadPrivateKey ( _
	keyFileOrString As String, _
	password As String _
) As StringBuilder
```

#### Parameters

keyFileOrString

:   Name of private key file or a PEM String containing the key

password

:   Password for private key, if encrypted; or "" if not

#### Return Value

StringBuilder containing an internal representation of the private key; or an empty StringBuilder if error

#### Remarks

This returns a StringBuilder, not a string, to allow secure wiping. Use sb.ToString() to obtain a string. Use Wipe.String(sb) to clear.

#### See Also

VB6/C equivalent: [`ECC_ReadPrivateKey`](#ECC_ReadPrivateKey)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Ecc_ReadPublicKey"></a>Ecc.ReadPublicKey Method

 Read from a file or string containing an EC public key into an "internal" public key string. 

#### Syntax

[`C#`]

```
public static StringBuilder ReadPublicKey(
	string keyFileOrString
)
```

[`VB.NET`]

```
Public Shared Function ReadPublicKey ( _
	keyFileOrString As String _
) As StringBuilder
```

#### Parameters

keyFileOrString

:   Name of public key file or a PEM String containing the key

#### Return Value

StringBuilder containing an internal representation of the public key; or an empty StringBuilder if error

#### Remarks

This returns a StringBuilder, not a string. Use sb.ToString() to obtain a string.

#### See Also

VB6/C equivalent: [`ECC_ReadPublicKey`](#ECC_ReadPublicKey)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Ecc_SaveEncKey"></a>Ecc.SaveEncKey Method

 Save an internal EC private key string to an encrypted private key file. 

#### Syntax

[`C#`]

```
public static int SaveEncKey(
	string outputFile,
	string internalKey,
	string password,
	Ecc.PbeScheme pbes,
	string paramString,
	Ecc.Format fileFormat
)
```

[`VB.NET`]

```
Public Shared Function SaveEncKey ( _
	outputFile As String, _
	internalKey As String, _
	password As String, _
	pbes As Ecc.PbeScheme, _
	paramString As String, _
	fileFormat As Ecc.Format _
) As Integer
```

#### Parameters

outputFile

:   name of key file to be created

internalKey

:   the private key in an internal key string

password

:   the password to be used for the encrypted key file

pbes

:   Type: [Ecc.PbeScheme](#T_Ecc_PbeScheme)  

Password-based encryption scheme to encrypt private key [default = pbeWithSHAAnd3-KeyTripleDES-CBC]

paramString

:   Optional parameters. A set of attribute name=value pairs separated by a semicolon ";" (see remarks). Set as "" for defaults.

fileFormat

:   Type: [Ecc.Format](#T_Ecc_Format)  

Format to save file [default = DER binary]

#### Return Value

Zero if successful or non-zero [error code](#errorcodes)

#### Remarks

Valid name-value pairs for paramString are:

 

| **count**=integer | To set the iteration count used in the PBKDF2 method, e.g. "count=5000;" [default=2048]. |
| --- | --- |
| **prf**=hmac-name | To change the HMAC algorithm used in the PBKDF2 method, e.g. "prf=hmacwithSHA256;" [default=hmacwithSHA1]. |

 Valid values for hmac-name are {hmacWithSHA1|hmacWithSHA224|hmacWithSHA256|hmacWithSHA384|hmacWithSHA512}.

#### See Also

VB6/C equivalent: [`ECC_SaveEncKey`](#ECC_SaveEncKey)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Ecc_SaveKey"></a>Ecc.SaveKey Method

 Save an internal EC key string (public or private) to an unencrypted key file. 

#### Syntax

[`C#`]

```
public static int SaveKey(
	string outputFile,
	string internalKey,
	Ecc.KeyType keyType,
	Ecc.Format fileFormat
)
```

[`VB.NET`]

```
Public Shared Function SaveKey ( _
	outputFile As String, _
	internalKey As String, _
	keyType As Ecc.KeyType, _
	fileFormat As Ecc.Format _
) As Integer
```

#### Parameters

outputFile

:   Name of key file to be created

internalKey

:   the private or public EC key in an internal key string

keyType

:   Type: [Ecc.KeyType](#T_Ecc_KeyType)  

Key structure for private key (ignored for public)

fileFormat

:   Type: [Ecc.Format](#T_Ecc_Format)  

Format to save file [default = DER binary]

#### Return Value

If successful, the return value is zero; otherwise it returns a nonzero [error code](#errorcodes)

#### See Also

VB6/C equivalent: [`ECC_SaveKey`](#ECC_SaveKey)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_General_CompileTime"></a>General.CompileTime Method

 Return date and time the core CryptoSys PKI DLL was last compiled. 

#### Syntax

[`C#`]

```
public static string CompileTime()
```

[`VB.NET`]

```
Public Shared Function CompileTime As String
```

#### Return Value

Date and time string

#### See Also

VB6/C equivalent: [`PKI_CompileTime`](#PKI_CompileTime)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_General_ErrorCode"></a>General.ErrorCode Method

 Return the [error code](#errorcodes) of the *first* error that occurred when calling the last function. 

#### Syntax

[`C#`]

```
public static int ErrorCode()
```

[`VB.NET`]

```
Public Shared Function ErrorCode As Integer
```

#### Return Value

Error code

#### See Also

VB6/C equivalent: [`PKI_ErrorCode`](#PKI_ErrorCode)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_General_ErrorLookup"></a>General.ErrorLookup Method

 Return a description of an [error code](#errorcodes). 

#### Syntax

[`C#`]

```
public static string ErrorLookup(
	int errCode
)
```

[`VB.NET`]

```
Public Shared Function ErrorLookup ( _
	errCode As Integer _
) As String
```

#### Parameters

errCode

:   Code number

#### Return Value

Corresponding error message

#### See Also

VB6/C equivalent: [`PKI_ErrorLookup`](#PKI_ErrorLookup)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_General_FormatErrorMessage"></a>General.FormatErrorMessage Method

 Return an error message string for the last error. 

#### Syntax

[`C#`]

```
public static string FormatErrorMessage(
	int errCode,
	string userMsg
)
```

[`VB.NET`]

```
Public Shared Function FormatErrorMessage ( _
	errCode As Integer, _
	userMsg As String _
) As String
```

#### Parameters

errCode

:   Error code returned by last call (*optional*)

userMsg

:   Optional message string

#### Return Value

Error message as a string Error (errCode) ...

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_General_LastError"></a>General.LastError Method

 Retrieve the last error message set by the toolkit. 

#### Syntax

[`C#`]

```
public static string LastError()
```

[`VB.NET`]

```
Public Shared Function LastError As String
```

#### Return Value

Final error message from last call (may be empty)

#### See Also

VB6/C equivalent: [`PKI_LastError`](#PKI_LastError)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_General_LicenceType"></a>General.LicenceType Method

 Return licence type. 

#### Syntax

[`C#`]

```
public static char LicenceType()
```

[`VB.NET`]

```
Public Shared Function LicenceType As Char
```

#### Return Value

D=Developer T=Trial

#### See Also

VB6/C equivalent: [`PKI_LicenceType`](#PKI_LicenceType)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_General_ModuleInfo"></a>General.ModuleInfo Method

 Get additional information about the core DLL module. 

#### Syntax

[`C#`]

```
public static string ModuleInfo()
```

[`VB.NET`]

```
Public Shared Function ModuleInfo As String
```

#### Return Value

Additional information, e.g. "Licensed Developer Edition".

#### See Also

VB6/C equivalent: [`PKI_ModuleInfo`](#PKI_ModuleInfo)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_General_ModuleName"></a>General.ModuleName Method

 Return full path name of core CryptoSys PKI DLL module. 

#### Syntax

[`C#`]

```
public static string ModuleName()
```

[`VB.NET`]

```
Public Shared Function ModuleName As String
```

#### Return Value

File name.

#### Remarks

If using the Win32 DLL in the system folder on a 64-bit system, Windows will return "C:\WINDOWS\SYSTEM32\diCrPKI.dll" when the DLL file path is actually "C:\WINDOWS\SYSWOW64\diCrPKI.dll". Use General.Platform() to find out exactly which DLL is being used.

#### See Also

VB6/C equivalent: [`PKI_ModuleName`](#PKI_ModuleName)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_General_NetVersion"></a>General.NetVersion Method

 Return the version of this .NET module. 

#### Syntax

[`C#`]

```
public static string NetVersion()
```

[`VB.NET`]

```
Public Shared Function NetVersion As String
```

#### Return Value

Version string, e.g. "20.1.0"

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_General_Platform"></a>General.Platform Method

 Return the platform the core DLL was compiled for. 

#### Syntax

[`C#`]

```
public static string Platform()
```

[`VB.NET`]

```
Public Shared Function Platform As String
```

#### Return Value

"Win32" or "X64"

#### See Also

VB6/C equivalent: [`PKI_Platform`](#PKI_Platform)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_General_PowerUpTests"></a>General.PowerUpTests Method

 Perform FIPS-140-2 start-up tests. 

#### Syntax

[`C#`]

```
public static int PowerUpTests()
```

[`VB.NET`]

```
Public Shared Function PowerUpTests As Integer
```

#### Return Value

Zero on success

#### See Also

VB6/C equivalent: [`PKI_PowerUpTests`](#PKI_PowerUpTests)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_General_Version"></a>General.Version Method

 Return the release version of the core CryptoSys PKI DLL as an integer value. 

#### Syntax

[`C#`]

```
public static int Version()
```

[`VB.NET`]

```
Public Shared Function Version As Integer
```

#### Return Value

Version number in form Major * 10000 + Minor * 100 + Release. For example, version 3.10.1 would return 31001.

#### See Also

VB6/C equivalent: [`PKI_Version`](#PKI_Version)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Hash_BytesFromBytes"></a>Hash.BytesFromBytes Method

 Create hash digest in byte format of byte input. 

#### Syntax

[`C#`]

```
public static byte[] BytesFromBytes(
	byte[] message,
	HashAlgorithm hashAlg
)
```

[`VB.NET`]

```
Public Shared Function BytesFromBytes ( _
	message As Byte(), _
	hashAlg As HashAlgorithm _
) As Byte()
```

#### Parameters

message

:   Message data in byte format

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash algorithm to be used

#### Return Value

Message digest in byte format

#### See Also

VB6/C equivalent: [`HASH_Bytes`](#HASH_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Hash_BytesFromFile"></a>Hash.BytesFromFile Method

 Create hash digest of a binary file. 

#### Syntax

[`C#`]

```
public static byte[] BytesFromFile(
	string fileName,
	HashAlgorithm hashAlg
)
```

[`VB.NET`]

```
Public Shared Function BytesFromFile ( _
	fileName As String, _
	hashAlg As HashAlgorithm _
) As Byte()
```

#### Parameters

fileName

:   Name of file containing message data

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash algorithm to be used

#### Return Value

Message digest in byte format

#### See Also

VB6/C equivalent: [`HASH_File`](#HASH_File)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Hash_Double"></a>Hash.Double Method

 Create double hash, i.e. hash of hash, in byte format of byte input. 

#### Syntax

[`C#`]

```
public static byte[] Double(
	byte[] message,
	HashAlgorithm hashAlg
)
```

[`VB.NET`]

```
Public Shared Function Double ( _
	message As Byte(), _
	hashAlg As HashAlgorithm _
) As Byte()
```

#### Parameters

message

:   Message data in byte format

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash algorithm to be used

#### Return Value

Message digest HASH(HASH(m)) in byte format

#### See Also

VB6/C equivalent: [`HASH_Bytes`](#HASH_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Hash_HexFromBytes"></a>Hash.HexFromBytes Method

 Create hash digest in hex format of byte input. 

#### Syntax

[`C#`]

```
public static string HexFromBytes(
	byte[] message,
	HashAlgorithm hashAlg
)
```

[`VB.NET`]

```
Public Shared Function HexFromBytes ( _
	message As Byte(), _
	hashAlg As HashAlgorithm _
) As String
```

#### Parameters

message

:   Message data in byte format

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash algorithm to be used

#### Return Value

Message digest in hex-encoded format

#### See Also

VB6/C equivalent: [`HASH_HexFromBytes`](#HASH_HexFromBytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Hash_HexFromFile"></a>Hash.HexFromFile Method

 Create hash digest in hex format of a binary file. 

#### Syntax

[`C#`]

```
public static string HexFromFile(
	string fileName,
	HashAlgorithm hashAlg
)
```

[`VB.NET`]

```
Public Shared Function HexFromFile ( _
	fileName As String, _
	hashAlg As HashAlgorithm _
) As String
```

#### Parameters

fileName

:   Name of file containing message data

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash algorithm to be used

#### Return Value

Message digest in hex-encoded format

#### See Also

VB6/C equivalent: [`HASH_HexFromFile`](#HASH_HexFromFile)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Hash_HexFromHex"></a>Hash.HexFromHex Method

 Create hash digest in hex format of hex-encoded input. 

#### Syntax

[`C#`]

```
public static string HexFromHex(
	string messageHex,
	HashAlgorithm hashAlg
)
```

[`VB.NET`]

```
Public Shared Function HexFromHex ( _
	messageHex As String, _
	hashAlg As HashAlgorithm _
) As String
```

#### Parameters

messageHex

:   Message data in hex-encoded format

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash algorithm to be used

#### Return Value

Message digest in hex-encoded format

#### See Also

VB6/C equivalent: [`HASH_HexFromHex`](#HASH_HexFromHex)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Hash_HexFromString"></a>Hash.HexFromString Method

 Create hash digest in hex format of string input. 

#### Syntax

[`C#`]

```
public static string HexFromString(
	string message,
	HashAlgorithm hashAlg
)
```

[`VB.NET`]

```
Public Shared Function HexFromString ( _
	message As String, _
	hashAlg As HashAlgorithm _
) As String
```

#### Parameters

message

:   Message data string

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash algorithm to be used

#### Return Value

Message digest in hex-encoded format

#### See Also

VB6/C equivalent: [`HASH_HexFromBytes`](#HASH_HexFromBytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Hash_HexFromTextFile"></a>Hash.HexFromTextFile Method

 Create hash digest in hex format of a text file, treating CR-LF (0x13, 0x10) pairs as a single LF (0x10). 

#### Syntax

[`C#`]

```
public static string HexFromTextFile(
	string fileName,
	HashAlgorithm hashAlg
)
```

[`VB.NET`]

```
Public Shared Function HexFromTextFile ( _
	fileName As String, _
	hashAlg As HashAlgorithm _
) As String
```

#### Parameters

fileName

:   Name of file containing message data

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash algorithm to be used

#### Return Value

Message digest in hex format

#### Remarks

This *should* give the same message digest of a text file on both Unix and Windows systems.

#### See Also

VB6/C equivalent: [`HASH_HexFromFile`](#HASH_HexFromFile)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Hash_Length"></a>Hash.Length Method

 Return length of message digest output in bytes. 

#### Syntax

[`C#`]

```
public static int Length(
	HashAlgorithm hashAlg
)
```

[`VB.NET`]

```
Public Shared Function Length ( _
	hashAlg As HashAlgorithm _
) As Integer
```

#### Parameters

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash algorithm

#### Return Value

Length of the hash function output in bytes.

#### See Also

VB6/C equivalent: [`HASH_Length`](#HASH_Length)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Hmac_BytesFromBytes"></a>Hmac.BytesFromBytes Method

 Create a keyed-hash HMAC in byte format from byte input. 

#### Syntax

[`C#`]

```
public static byte[] BytesFromBytes(
	byte[] message,
	byte[] key,
	HashAlgorithm hashAlg
)
```

[`VB.NET`]

```
Public Shared Function BytesFromBytes ( _
	message As Byte(), _
	key As Byte(), _
	hashAlg As HashAlgorithm _
) As Byte()
```

#### Parameters

message

:   Message to be signed in byte format

key

:   Key in byte format

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash algorithm to be used

#### Return Value

HMAC in byte format

#### See Also

VB6/C equivalent: [`HMAC_Bytes`](#HMAC_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Hmac_HexFromBytes"></a>Hmac.HexFromBytes Method

 Create a keyed-hash HMAC in hex-encoded format from byte input. 

#### Syntax

[`C#`]

```
public static string HexFromBytes(
	byte[] message,
	byte[] key,
	HashAlgorithm hashAlg
)
```

[`VB.NET`]

```
Public Shared Function HexFromBytes ( _
	message As Byte(), _
	key As Byte(), _
	hashAlg As HashAlgorithm _
) As String
```

#### Parameters

message

:   Message to be signed in byte format

key

:   Key in byte format

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash algorithm to be used

#### Return Value

HMAC in hex-encoded format

#### See Also

VB6/C equivalent: [`HMAC_HexFromBytes`](#HMAC_HexFromBytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Hmac_HexFromHex"></a>Hmac.HexFromHex Method

 Create a keyed-hash HMAC in hex-encoded format from hex-encoded input. 

#### Syntax

[`C#`]

```
public static string HexFromHex(
	string messageHex,
	string keyHex,
	HashAlgorithm hashAlg
)
```

[`VB.NET`]

```
Public Shared Function HexFromHex ( _
	messageHex As String, _
	keyHex As String, _
	hashAlg As HashAlgorithm _
) As String
```

#### Parameters

messageHex

:   Message to be signed in hex-encoded format

keyHex

:   Key in hex-encoded format

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash algorithm to be used

#### Return Value

HMAC in hex-encoded format

#### See Also

VB6/C equivalent: [`HMAC_HexFromHex`](#HMAC_HexFromHex)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Hpke_DerivePrivateKey"></a>Hpke.DerivePrivateKey Method

 Derive an EC private key in a deterministic manner from input keying material using the DeriveKeyPair algorithm in RFC9180. 

#### Syntax

[`C#`]

```
public static string DerivePrivateKey(
	byte[] ikm,
	Hpke.CurveName curveName,
	Hpke.OutputOpts opts
)
```

[`VB.NET`]

```
Public Shared Function DerivePrivateKey ( _
	ikm As Byte(), _
	curveName As Hpke.CurveName, _
	opts As Hpke.OutputOpts _
) As String
```

#### Parameters

ikm

:   Input key material (ikm). This *must* have length in bytes at least as long as the key to be produced.

curveName

:   Type: [Hpke.CurveName](#T_Hpke_CurveName)  

Curve name

opts

:   Type: [Hpke.OutputOpts](#T_Hpke_OutputOpts)  

Output options (default=internal key format)

#### Return Value

Derived private key in string form or an empty string on error.

#### Remarks

By default the key is output as an ephemeral "internal" key string, which can be used directly with Ecc.SaveKey, Ecc.SaveEncKey, Ecc.PublicKeyFromPrivate, Ecc.DHSharedSecret and Ecc.QueryKey. If opts is set to `OutputOpts.KeyAsHex` then the key is output in serialized hexadecimal form in the same manner as the test vectors in [RFC9180] (without the clamping). The KDF to be used is fixed by the EC curve group as follows: 

| EC curve | KDF |
| --- | --- |
| P-256 | HKDF-SHA256 |
| P-384 | HKDF-SHA384 |
| P-521 | HKDF-SHA512 |
| X25519 | HKDF-SHA256 |
| X448 | HKDF-SHA512 |

#### Example

[`C#`]

```
string ikmhex = "7268600d403fce431561aef583ee1613527cff655c1343f29812e66706df3234";
string skhex = Hpke.DerivePrivateKey(Cnv.FromHex(ikmhex), Hpke.CurveName.X25519, Hpke.OutputOpts.KeyAsHex);
// 52c4a758a802cd8b936eceea314432798d5baf2d7e9235dc084ab1b9cfa2f736
```

#### See Also

VB6/C equivalent: [`HPKE_DerivePrivateKey`](#HPKE_DerivePrivateKey)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Hpke_LabeledExpand"></a>Hpke.LabeledExpand Method

 Compute the output of the LabeledExpand function as defined in RFC9180. 

#### Syntax

[`C#`]

```
public static byte[] LabeledExpand(
	int numBytes,
	byte[] prk,
	string label,
	byte[] info,
	Hpke.CurveName curveName,
	Hpke.AeadAlg aeadAlg
)
```

[`VB.NET`]

```
Public Shared Function LabeledExpand ( _
	numBytes As Integer, _
	prk As Byte(), _
	label As String, _
	info As Byte(), _
	curveName As Hpke.CurveName, _
	aeadAlg As Hpke.AeadAlg _
) As Byte()
```

#### Parameters

numBytes

:   Required number of bytes (L) of output keying material.

prk

:   Pseudorandom key (prk)

label

:   Label string

info

:   Byte string info

curveName

:   Type: [Hpke.CurveName](#T_Hpke_CurveName)  

ECDH curve used in scheme

aeadAlg

:   Type: [Hpke.AeadAlg](#T_Hpke_AeadAlg)  

AEAD encryption algorithm used in the scheme or 0 (default) to indicate KDF is being used inside a KEM algorithm.

#### Return Value

L bytes of output keying material.

#### Remarks

The LabeledExpand function is defined in section 4 of [RFC9180]. It uses the "expand" stage of the HKDF function [RFC5869]. The ECDH curve group used in the scheme must be specified, which automatically fixes the KDF and associated HMAC algorithm to be used.

#### Example

[`C#`]

```
int Nk = 16;
// key = LabeledExpand(secret, 'key', key_schedule_context, Nk)
byte[] key = Hpke.LabeledExpand(Nk, Cnv.FromHex("12fff91991e93b48de37e7daddb52981084bd8aa64289c3788471d9a9712f397"), "key",
   Cnv.FromHex("00725611c9d98c07c03f60095cd32d400d8347d45ed67097bbad50fc56da742d07cb6cffde367bb0565ba28bb02c90744a20f5ef37f30523526106f637abb05449"),
   Hpke.CurveName.X25519, Hpke.AeadAlg.Aes_128_Gcm);
// 4531685d41d65f03dc48f6b8302c05b0
```

#### See Also

VB6/C equivalent: [`HPKE_LabeledExpand`](#HPKE_LabeledExpand)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Hpke_LabeledExtract"></a>Hpke.LabeledExtract Method

 Compute the output of the LabeledExtract function as defined in RFC9180. 

#### Syntax

[`C#`]

```
public static byte[] LabeledExtract(
	byte[] salt,
	string label,
	byte[] ikm,
	Hpke.CurveName curveName,
	Hpke.AeadAlg aeadAlg
)
```

[`VB.NET`]

```
Public Shared Function LabeledExtract ( _
	salt As Byte(), _
	label As String, _
	ikm As Byte(), _
	curveName As Hpke.CurveName, _
	aeadAlg As Hpke.AeadAlg _
) As Byte()
```

#### Parameters

salt

:   Byte string salt

label

:   Label string

ikm

:   Input keying material (ikm)

curveName

:   Type: [Hpke.CurveName](#T_Hpke_CurveName)  

ECDH curve used in scheme

aeadAlg

:   Type: [Hpke.AeadAlg](#T_Hpke_AeadAlg)  

AEAD encryption algorithm used in the scheme or 0 (default) to indicate KDF is being used inside a KEM algorithm.

#### Return Value

A pseudorandom key of fixed length Nh bytes.

#### Remarks

The LabeledExtract function is defined in section 4 of [RFC9180]. It uses the "extract" stage of the HKDF function [RFC5869] and outputs a fixed value of bytes equal to the length (Nh) of the underlying HMAC function used by the KDF algorithm. The ECDH curve group used in the scheme must be specified, which automatically fixes the KDF and associated HMAC algorithm to be used.

#### Example

[`C#`]

```
// Used inside KEM
string ikmhex = "7268600d403fce431561aef583ee1613527cff655c1343f29812e66706df3234";
Console.WriteLine(Cnv.ToHex(Hpke.LabeledExtract(null, "dkp_prk", Cnv.FromHex(ikmhex), Hpke.CurveName.X25519)));
// 7B8BFE1D6F3D0CB45C585E133299C64AC998BF46CAF2DC13BA874F23413EC23A
// Used outside KEM
Console.WriteLine(Cnv.ToHex(Hpke.LabeledExtract(null, "psk_id_hash", null, Hpke.CurveName.X25519, Hpke.AeadAlg.Aes_128_Gcm)));
// 725611C9D98C07C03F60095CD32D400D8347D45ED67097BBAD50FC56DA742D07
```

#### See Also

VB6/C equivalent: [`HPKE_LabeledExtract`](#HPKE_LabeledExtract)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Kdf_Bytes"></a>Kdf.Bytes Method

 Generate a key-encryption key (KEK) from input keying material (IKM) using a key derivation function (KDF). 

#### Syntax

[`C#`]

```
public static byte[] Bytes(
	int dkLen,
	byte[] ikm,
	Kdf.KdfAlg kdfAlg,
	Kdf.HashAlg hashAlg,
	byte[] sharedInfo,
	string paramString
)
```

[`VB.NET`]

```
Public Shared Function Bytes ( _
	dkLen As Integer, _
	ikm As Byte(), _
	kdfAlg As Kdf.KdfAlg, _
	hashAlg As Kdf.HashAlg, _
	sharedInfo As Byte(), _
	paramString As String _
) As Byte()
```

#### Parameters

dkLen

:   Required length of output key material in bytes.

ikm

:   Input key material/shared secret.

kdfAlg

:   Type: [Kdf.KdfAlg](#T_Kdf_KdfAlg)  

Key derivation function to use.

hashAlg

:   Type: [Kdf.HashAlg](#T_Kdf_HashAlg)  

Hash algorithm to use with the key derivation function (default is SHA-1)

sharedInfo

:   SharedInfo (optional)

paramString

:   Optional parameters. Set as "" for defaults. Pass attribute-value salt=<hex-digits> to set the optional salt parameter for the HKDF algorithm, e.g. "salt=606162636465666768696a6b6c6d6e6f;"

#### Return Value

Output key material (KEK).

#### See Also

VB6/C equivalent: [`KDF_Bytes`](#KDF_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Kdf_ForCms"></a>Kdf.ForCms Method

 Generate a key-encryption key (KEK) for ECDH key exchange in a CMS EnvelopedData object. 

#### Syntax

[`C#`]

```
public static byte[] ForCms(
	byte[] zz,
	Kdf.KeyWrapAlg keyWrapAlg,
	Kdf.KdfAlg kdfAlg,
	Kdf.HashAlg hashAlg,
	byte[] ukm
)
```

[`VB.NET`]

```
Public Shared Function ForCms ( _
	zz As Byte(), _
	keyWrapAlg As Kdf.KeyWrapAlg, _
	kdfAlg As Kdf.KdfAlg, _
	hashAlg As Kdf.HashAlg, _
	ukm As Byte() _
) As Byte()
```

#### Parameters

zz

:   Input key material/shared secret value (denoted variously as ZZ/Z/K/IKM)

keyWrapAlg

:   Type: [Kdf.KeyWrapAlg](#T_Kdf_KeyWrapAlg)  

Key wrap algorithm (required, cannot be Default)

kdfAlg

:   Type: [Kdf.KdfAlg](#T_Kdf_KdfAlg)  

Key derivation function to use.

hashAlg

:   Type: [Kdf.HashAlg](#T_Kdf_HashAlg)  

Hash algorithm to use with the key derivation function (default is SHA-1)

ukm

:   Optional user key material (ukm)

#### Return Value

Output key material (KEK).

#### Remarks

This is a specialist function using the key definition algorithms described in [RFC5753] and [RFC8418] when used for key agreement with ECDH in a CMS EnvelopedData object. The key-encryption key is derived using the ECC-CMS-SharedInfo type, described in section 7.2 of [RFC5753].

#### See Also

VB6/C equivalent: [`KDF_ForCms`](#KDF_ForCms)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Ocsp_MakeRequest"></a>Ocsp.MakeRequest Method

 Create an Online Certification Status Protocol (OCSP) request as a base64 string. 

#### Syntax

[`C#`]

```
public static string MakeRequest(
	string issuerCert,
	string certFileOrSerialNumber,
	HashAlgorithm hashAlg
)
```

[`VB.NET`]

```
Public Shared Function MakeRequest ( _
	issuerCert As String, _
	certFileOrSerialNumber As String, _
	hashAlg As HashAlgorithm _
) As String
```

#### Parameters

issuerCert

:   name of issuer's X.509 certificate file (or base64 representation)

certFileOrSerialNumber

:   either the name of X.509 certificate file to be checked or its serial number in hexadecimal format preceded by #x

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash algorithm to be used [default = SHA-1]

#### Return Value

A base64 string suitable for an OCSP request to an Online Certificate Status Manager or an empty string on error.

#### Remarks

The issuer's X.509 certficate must be specified. The certificate to be checked can either be specified directly as a filename or as a serialNumber in hexadecimal format preceded by "#x", e.g. "#x01deadbeef". If the latter format is used, it must be in hexadecimal format, so the serial number 10 would be passed as "#x0a". It is an error (NO_MATCH_ERROR) if the issuer's name of the certificate to be checked does not match the subject name of the issuer's certificate.

#### See Also

VB6/C equivalent: [`OCSP_MakeRequest`](#OCSP_MakeRequest)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Ocsp_ReadResponse"></a>Ocsp.ReadResponse Method

 Read a response to an Online Certification Status Protocol (OCSP) request and outputs the main results in text form. 

#### Syntax

[`C#`]

```
public static string ReadResponse(
	string responseFile,
	string issuerCert
)
```

[`VB.NET`]

```
Public Shared Function ReadResponse ( _
	responseFile As String, _
	issuerCert As String _
) As String
```

#### Parameters

responseFile

:   name of the file containing the response data in BER format.

issuerCert

:   (optional) name of issuer's X.509 certificate file (or base64 representation)

#### Return Value

A text string outlining the main results in the response data or an empty string on error.

#### Remarks

Note that a revoked certificate will still result in a "Successful response", so check the CertStatus. The issuer's X.509 certficate issuerCert is optional. If provided, it will be used to check the signature on the OCSP reponse and and an error will result if the signature is not valid. **CAUTION:** For some CAs (e.g. VeriSign) the key used to sign the OCSP response is not the same as the key in the issuer's certificate, so specifying the issuer's certificate in this case will result in a signature error. If you can separately obtain the certificate used to sign the OCSP response, then specify this as the issuerCert; otherwise leave as the empty string "".

#### See Also

VB6/C equivalent: [`OCSP_ReadResponse`](#OCSP_ReadResponse)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Pbe_Kdf2_Int32ByteByteInt32HashAlgorithm"></a>Pbe.Kdf2 Method (Int32, Byte[], Byte[], Int32, HashAlgorithm)

 Derive a key of any length from a password using the PBKDF2 algorithm from PKCS #5 v2.1. 

#### Syntax

[`C#`]

```
public static byte[] Kdf2(
	int dkLen,
	byte[] pwdBytes,
	byte[] salt,
	int count,
	HashAlgorithm hashAlg
)
```

[`VB.NET`]

```
Public Shared Function Kdf2 ( _
	dkLen As Integer, _
	pwdBytes As Byte(), _
	salt As Byte(), _
	count As Integer, _
	hashAlg As HashAlgorithm _
) As Byte()
```

#### Parameters

dkLen

:   Required length of key in bytes

pwdBytes

:   Password in byte format

salt

:   Salt in byte format

count

:   Iteration count

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash algorithm to use in HMAC PRF (default is SHA-1)

#### Return Value

Key in byte[] format

#### See Also

VB6/C equivalent: [`PBE_Kdf2`](#PBE_Kdf2)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Pbe_Kdf2_Int32StringStringInt32HashAlgorithm"></a>Pbe.Kdf2 Method (Int32, String, String, Int32, HashAlgorithm)

 Derive a key in hex format of any length from a password with the salt in hex format. 

#### Syntax

[`C#`]

```
public static string Kdf2(
	int dkLen,
	string pwdStr,
	string saltHex,
	int count,
	HashAlgorithm hashAlg
)
```

[`VB.NET`]

```
Public Shared Function Kdf2 ( _
	dkLen As Integer, _
	pwdStr As String, _
	saltHex As String, _
	count As Integer, _
	hashAlg As HashAlgorithm _
) As String
```

#### Parameters

dkLen

:   Required length of key in bytes

pwdStr

:   Password

saltHex

:   Salt in hex format

count

:   Iteration count

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash algorithm to use in HMAC PRF (default is SHA-1)

#### Return Value

Key in hex format

#### See Also

VB6/C equivalent: [`PBE_Kdf2Hex`](#PBE_Kdf2Hex)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Pbe_Scrypt_Int32ByteByteInt32Int32Int32"></a>Pbe.Scrypt Method (Int32, Byte[], Byte[], Int32, Int32, Int32)

 Derives a key of any length from a password using the SCRYPT algorithm. 

#### Syntax

[`C#`]

```
public static byte[] Scrypt(
	int dkLen,
	byte[] pwdBytes,
	byte[] salt,
	int N,
	int r,
	int p
)
```

[`VB.NET`]

```
Public Shared Function Scrypt ( _
	dkLen As Integer, _
	pwdBytes As Byte(), _
	salt As Byte(), _
	N As Integer, _
	r As Integer, _
	p As Integer _
) As Byte()
```

#### Parameters

dkLen

:   Required length of key in bytes

pwdBytes

:   Password encoded in byte format

salt

:   Salt in byte format

N

:   CPU/Memory cost parameter, a number greater than one and a power of 2.

r

:   Block size r

p

:   Parallelization parameter p

#### Return Value

Key in byte[] format

#### See Also

VB6/C equivalent: [`PBE_Scrypt`](#PBE_Scrypt)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Pbe_Scrypt_Int32StringStringInt32Int32Int32"></a>Pbe.Scrypt Method (Int32, String, String, Int32, Int32, Int32)

 Derives a key in hex format from a password with the salt in hex format 

#### Syntax

[`C#`]

```
public static string Scrypt(
	int dkLen,
	string pwdStr,
	string saltHex,
	int N,
	int r,
	int p
)
```

[`VB.NET`]

```
Public Shared Function Scrypt ( _
	dkLen As Integer, _
	pwdStr As String, _
	saltHex As String, _
	N As Integer, _
	r As Integer, _
	p As Integer _
) As String
```

#### Parameters

dkLen

:   Required length of key in bytes

pwdStr

:   Password (normal text)

saltHex

:   Salt in hex format

N

:   CPU/Memory cost parameter, a number greater than one and a power of 2.

r

:   Block size r

p

:   Parallelization parameter p

#### Return Value

Key in hex format

#### Remarks

Password pwdStr is normal text, not hexadecimal

#### Example

[`C#`]

```
string keyHex = Pbe.Scrypt(64, "password", "4E61436C", 1024, 8, 16);
```

#### See Also

VB6/C equivalent: [`PBE_ScryptHex`](#PBE_ScryptHex)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Pem_FileFromBinFile"></a>Pem.FileFromBinFile Method

 Create a PEM file from a binary file with option for line endings. 

#### Syntax

[`C#`]

```
public static int FileFromBinFile(
	string fileToMake,
	string fileIn,
	string header,
	int lineLen,
	bool unixEOL
)
```

[`VB.NET`]

```
Public Shared Function FileFromBinFile ( _
	fileToMake As String, _
	fileIn As String, _
	header As String, _
	lineLen As Integer, _
	unixEOL As Boolean _
) As Integer
```

#### Parameters

fileToMake

:   Name of PEM file to create

fileIn

:   Name of input binary file

header

:   Header to be used. Leave empty to omit the PEM header and footer.

lineLen

:   Maximum length of a line in the resulting PEM file [default = 64 characters]

unixEOL

:   Set true for Unix/SSL LF line endings [optional, default = Windows CR-LF endings]

#### Return Value

Zero if successful; otherwise it returns an [error code](#errorcodes)

#### See Also

VB6/C equivalent: [`PEM_FileFromBinFile`](#PEM_FileFromBinFile)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Pem_FileToBinFile"></a>Pem.FileToBinFile Method

 Convert the contents of a PEM file into a binary file. 

#### Syntax

[`C#`]

```
public static int FileToBinFile(
	string fileToMake,
	string fileIn
)
```

[`VB.NET`]

```
Public Shared Function FileToBinFile ( _
	fileToMake As String, _
	fileIn As String _
) As Integer
```

#### Parameters

fileToMake

:   Name of binary file to create.

fileIn

:   Name of input PEM file

#### Return Value

Zero if successful; otherwise it returns an [error code](#errorcodes)

#### See Also

VB6/C equivalent: [`PEM_FileToBinFile`](#PEM_FileToBinFile)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Pfx_MakeFile"></a>Pfx.MakeFile Method

 Create a PFX (PKCS-12) file from an X.509 certificate and (optional) encrypted private key file with advanced options. 

#### Syntax

[`C#`]

```
public static int MakeFile(
	string fileToMake,
	string certFile,
	string privateKeyFile,
	string password,
	string friendlyName,
	Pfx.Options pfxOptions
)
```

[`VB.NET`]

```
Public Shared Function MakeFile ( _
	fileToMake As String, _
	certFile As String, _
	privateKeyFile As String, _
	password As String, _
	friendlyName As String, _
	pfxOptions As Pfx.Options _
) As Integer
```

#### Parameters

fileToMake

:   name of output file to be created

certFile

:   filename of the subject's X.509 certificate (required)

privateKeyFile

:   filename of the subject's encrypted private key in pkcs-8 format (optional)

password

:   password for private key file and new PFX file

friendlyName

:   friendly name identification for the subject (optional)

pfxOptions

:   Type: [Pfx.Options](#T_Pfx_Options)  

Specialist options

#### Return Value

Zero if successful or a non-zero [error code](#errorcodes).

#### Remarks

The default behaviour is to encrypt the certificate using "weak" 40-bit RC2 and the private key (if provided) using "standard" Triple DES (pbeWithSHAAnd3-KeyTripleDES-CBC).

#### See Also

VB6/C equivalent: [`PFX_MakeFile`](#PFX_MakeFile)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Pfx_SignatureIsValid"></a>Pfx.SignatureIsValid Method

 Verify the MacData signature in a PKCS-12 file. 

#### Syntax

[`C#`]

```
public static bool SignatureIsValid(
	string fileName,
	string password
)
```

[`VB.NET`]

```
Public Shared Function SignatureIsValid ( _
	fileName As String, _
	password As String _
) As Boolean
```

#### Parameters

fileName

:   Name of PKCS-12 file to be checked

password

:   password for file

#### Return Value

true if signature is OK

#### See Also

VB6/C equivalent: [`PFX_VerifySig`](#PFX_VerifySig)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Prf_Bytes"></a>Prf.Bytes Method

 Generate output bytes using a pseudorandom function (PRF). 

#### Syntax

[`C#`]

```
public static byte[] Bytes(
	int numBytes,
	byte[] message,
	byte[] key,
	Prf.Alg prfAlg,
	string customStr
)
```

[`VB.NET`]

```
Public Shared Function Bytes ( _
	numBytes As Integer, _
	message As Byte(), _
	key As Byte(), _
	prfAlg As Prf.Alg, _
	customStr As String _
) As Byte()
```

#### Parameters

numBytes

:   Required number of output bytes.

message

:   Input message data.

key

:   Key.

prfAlg

:   Type: [Prf.Alg](#T_Prf_Alg)  

PRF algorithm.

customStr

:   Customization string (optional).

#### Return Value

Output data in byte array.

#### See Also

VB6/C equivalent: [`PRF_Bytes`](#PRF_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Pwd_Prompt"></a>Pwd.Prompt Method

 Open a dialog box to receive a password with user-supplied prompt. 

#### Syntax

[`C#`]

```
public static string Prompt(
	int maxChars,
	string caption,
	string prompt
)
```

[`VB.NET`]

```
Public Shared Function Prompt ( _
	maxChars As Integer, _
	caption As String, _
	prompt As String _
) As String
```

#### Parameters

maxChars

:   Maximum characters expected in password

caption

:   Caption for dialog window

prompt

:   Wording for prompt (optional, default="Enter password:")

#### Return Value

String containing password or Empty string if user cancels

#### See Also

VB6/C equivalent: [`PWD_Prompt`](#PWD_Prompt)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rng_Bytes_Int32"></a>Rng.Bytes Method (Int32)

 Generate an array of random bytes. 

#### Syntax

[`C#`]

```
public static byte[] Bytes(
	int numBytes
)
```

[`VB.NET`]

```
Public Shared Function Bytes ( _
	numBytes As Integer _
) As Byte()
```

#### Parameters

numBytes

:   Required number of random bytes

#### Return Value

Array of random bytes

#### See Also

VB6/C equivalent: [`RNG_Bytes`](#RNG_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rng_Bytes_Int32Byte"></a>Rng.Bytes Method (Int32, Byte[])

 Generate an array of random bytes with user-supplied entropy. 

#### Syntax

[`C#`]

```
public static byte[] Bytes(
	int numBytes,
	byte[] arrSeed
)
```

[`VB.NET`]

```
Public Shared Function Bytes ( _
	numBytes As Integer, _
	arrSeed As Byte() _
) As Byte()
```

#### Parameters

numBytes

:   Required number of random bytes

arrSeed

:   User-supplied entropy in byte format

#### Return Value

Array of random bytes

#### See Also

VB6/C equivalent: [`RNG_Bytes`](#RNG_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rng_Bytes_Int32String"></a>Rng.Bytes Method (Int32, String)

 Generate an array of random bytes with user-supplied entropy. 

#### Syntax

[`C#`]

```
public static byte[] Bytes(
	int numBytes,
	string seedStr
)
```

[`VB.NET`]

```
Public Shared Function Bytes ( _
	numBytes As Integer, _
	seedStr As String _
) As Byte()
```

#### Parameters

numBytes

:   Required number of random bytes

seedStr

:   User-supplied entropy in string format

#### Return Value

Array of random bytes

#### See Also

VB6/C equivalent: [`RNG_Bytes`](#RNG_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rng_BytesWithPrompt_Int32Rng_Strength"></a>Rng.BytesWithPrompt Method (Int32, Rng.Strength)

 Generate an array of random bytes with a prompt for random keyboard input. 

#### Syntax

[`C#`]

```
public static byte[] BytesWithPrompt(
	int numBytes,
	Rng.Strength strength
)
```

[`VB.NET`]

```
Public Shared Function BytesWithPrompt ( _
	numBytes As Integer, _
	strength As Rng.Strength _
) As Byte()
```

#### Parameters

numBytes

:   Required number of random bytes

strength

:   Type: [Rng.Strength](#T_Rng_Strength)  

Estimated security strength (default=112 bits)

#### Return Value

Array of random bytes

#### See Also

VB6/C equivalent: [`RNG_BytesWithPrompt`](#RNG_BytesWithPrompt)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rng_BytesWithPrompt_Int32StringRng_Strength"></a>Rng.BytesWithPrompt Method (Int32, String, Rng.Strength)

 Generate an array of random bytes with a prompt for random keyboard input. 

#### Syntax

[`C#`]

```
public static byte[] BytesWithPrompt(
	int numBytes,
	string prompt,
	Rng.Strength strength
)
```

[`VB.NET`]

```
Public Shared Function BytesWithPrompt ( _
	numBytes As Integer, _
	prompt As String, _
	strength As Rng.Strength _
) As Byte()
```

#### Parameters

numBytes

:   Required number of random bytes

prompt

:   Alternative prompt. Set as an empty string "" for the default prompt.

strength

:   Type: [Rng.Strength](#T_Rng_Strength)  

Required security strength

#### Return Value

Array of random bytes

#### See Also

VB6/C equivalent: [`RNG_BytesWithPrompt`](#RNG_BytesWithPrompt)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rng_Guid"></a>Rng.Guid Method

 Generate a random 36-character Global Unique IDentifier (GUID) string according to [RFC4122]. 

#### Syntax

[`C#`]

```
public static string Guid()
```

[`VB.NET`]

```
Public Shared Function Guid As String
```

#### Return Value

String of the form "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" where 'x' is a hexadecimal digit [0-9a-f].

#### See Also

VB6/C equivalent: [`RNG_Guid`](#RNG_Guid)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rng_Initialize"></a>Rng.Initialize Method

 Initialize the RNG generator with a seed file. 

#### Syntax

[`C#`]

```
public static bool Initialize(
	string seedFile
)
```

[`VB.NET`]

```
Public Shared Function Initialize ( _
	seedFile As String _
) As Boolean
```

#### Parameters

seedFile

:   Full path name of seed file

#### Return Value

true if successful; false if fails

#### Remarks

If the seed file does not exist, it will be created (with any available entropy).

#### See Also

VB6/C equivalent: [`RNG_Initialize`](#RNG_Initialize)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rng_InitializeEx"></a>Rng.InitializeEx Method

 Query and initialize the RNG generator using Intel(R) DRNG, if available. 

#### Syntax

[`C#`]

```
public static int InitializeEx(
	Rng.Options opts
)
```

[`VB.NET`]

```
Public Shared Function InitializeEx ( _
	opts As Rng.Options _
) As Integer
```

#### Parameters

opts

:   Type: [Rng.Options](#T_Rng_Options)  

Specify Rng.Options.NoIntelDrng to explicitly *turn off* support.

#### Return Value

Support status for Intel(R) DRNG. If available, then a positive value (1,2,3); else a negative [error code](#errorcodes).

#### See Also

VB6/C equivalent: [`RNG_Initialize`](#RNG_Initialize)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rng_MakeSeedFile"></a>Rng.MakeSeedFile Method

 Create a new seed file suitable for use with Rng.Initialize. 

#### Syntax

[`C#`]

```
public static bool MakeSeedFile(
	string seedFile,
	Rng.Strength strength
)
```

[`VB.NET`]

```
Public Shared Function MakeSeedFile ( _
	seedFile As String, _
	strength As Rng.Strength _
) As Boolean
```

#### Parameters

seedFile

:   Name of seed file to be created

strength

:   Type: [Rng.Strength](#T_Rng_Strength)  

Estimated security strength (default=112 bits)

#### Return Value

true if successful; false if fails

#### Remarks

Any existing file will be overwritten.

#### See Also

VB6/C equivalent: [`RNG_MakeSeedFile`](#RNG_MakeSeedFile)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rng_Number"></a>Rng.Number Method

 Generate a random number (integer) in a given range. 

#### Syntax

[`C#`]

```
public static int Number(
	int lower,
	int upper
)
```

[`VB.NET`]

```
Public Shared Function Number ( _
	lower As Integer, _
	upper As Integer _
) As Integer
```

#### Parameters

lower

:   lower value of range

upper

:   upper value of range

#### Return Value

Random integer x: lower <= x <= upper

#### See Also

VB6/C equivalent: [`RNG_Number`](#RNG_Number)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rng_Octet"></a>Rng.Octet Method

 Generate a single random octet (byte). 

#### Syntax

[`C#`]

```
public static byte Octet()
```

[`VB.NET`]

```
Public Shared Function Octet As Byte
```

#### Return Value

Single byte value randomly chosen between 0 and 255

#### See Also

VB6/C equivalent: [`RNG_Number`](#RNG_Number)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rng_Test"></a>Rng.Test Method

 Carry out a NIST SP800-90 health check and FIPS140-2 statistical tests on the random number generator. 

#### Syntax

[`C#`]

```
public static bool Test(
	string resultFile
)
```

[`VB.NET`]

```
Public Shared Function Test ( _
	resultFile As String _
) As Boolean
```

#### Parameters

resultFile

:   Name of results file to be created, or null not to create a results file.

#### Return Value

true if successful; false if fails

#### Remarks

Any existing file will be overwritten.

#### See Also

VB6/C equivalent: [`RNG_Test`](#RNG_Test)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rng_TestDrbgvs"></a>Rng.TestDrbgvs Method

 Test the RNG for conformance to NIST SP800-90A using the relevant test specified in DRBGVS. 

#### Syntax

[`C#`]

```
public static string TestDrbgvs(
	int returnedBitsLen,
	string entropyInput,
	string nonce,
	string personalizationString,
	string additionalInput1,
	string entropyReseed,
	string additionalInputReseed,
	string additionalInput2
)
```

[`VB.NET`]

```
Public Shared Function TestDrbgvs ( _
	returnedBitsLen As Integer, _
	entropyInput As String, _
	nonce As String, _
	personalizationString As String, _
	additionalInput1 As String, _
	entropyReseed As String, _
	additionalInputReseed As String, _
	additionalInput2 As String _
) As String
```

#### Parameters

returnedBitsLen

:   Number of bits to be returned from each call to the generate function in the test

entropyInput

:   the EntropyInput value in hex format

nonce

:   the Nonce value in hex format

personalizationString

:   the PersonalizationString value in hex format

additionalInput1

:   the first AdditionalInput value in hex format

entropyReseed

:   the EntropyReseed value in hex format

additionalInputReseed

:   the AdditionalInputReseed value in hex format

additionalInput2

:   the second AdditionalInput value in hex format

#### Return Value

the ReturnedBits as a string in hexadecimal format

#### Remarks

The test procedure, the input values and the expected output are described in the DRBGVS document. The relevant DRBG mechanism is HMAC_DRBG SHA-512 without prediction resistance. Use the empty string "" to pass a zero-length input. All hex strings must have an even number of characters.

#### See Also

VB6/C equivalent: [`RNG_TestDRBGVS`](#RNG_TestDRBGVS)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rng_UpdateSeedFile"></a>Rng.UpdateSeedFile Method

 Update the RNG seed file. 

#### Syntax

[`C#`]

```
public static bool UpdateSeedFile(
	string seedFile
)
```

[`VB.NET`]

```
Public Shared Function UpdateSeedFile ( _
	seedFile As String _
) As Boolean
```

#### Parameters

seedFile

:   Full path name of seed file

#### Return Value

true if successful; false if fails

#### Remarks

The seed file must be writable. If it does not exist it will be created (with any available entropy). Any existing file of the same name will be overwritten without warning.

#### See Also

VB6/C equivalent: [`RNG_UpdateSeedFile`](#RNG_UpdateSeedFile)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_CheckKey_String"></a>Rsa.CheckKey Method (String)

 Check the validity of an "internal" RSA public or private key. 

#### Syntax

[`C#`]

```
public static int CheckKey(
	string intKeyString
)
```

[`VB.NET`]

```
Public Shared Function CheckKey ( _
	intKeyString As String _
) As Integer
```

#### Parameters

intKeyString

:   Internal key string

#### Return Value

0=valid private key, 1=valid publickey, or negative [error code](#errorcodes)

#### Remarks

A private key is also validated for consistency.

#### See Also

VB6/C equivalent: [`RSA_CheckKey`](#RSA_CheckKey)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_CheckKey_StringBuilder"></a>Rsa.CheckKey Method (StringBuilder)

 Check the validity of an "internal" RSA public or private key. 

#### Syntax

[`C#`]

```
public static int CheckKey(
	StringBuilder sbKeyString
)
```

[`VB.NET`]

```
Public Shared Function CheckKey ( _
	sbKeyString As StringBuilder _
) As Integer
```

#### Parameters

sbKeyString

:   Internal key string

#### Return Value

0=valid private key, 1=valid publickey, or negative [error code](#errorcodes)

#### Remarks

A private key is also validated for consistency.

#### See Also

VB6/C equivalent: [`RSA_CheckKey`](#RSA_CheckKey)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_DecodeDigestForSignature"></a>Rsa.DecodeDigestForSignature Method

 Decode an encoded message for signature. 

#### Syntax

[`C#`]

```
public static byte[] DecodeDigestForSignature(
	byte[] data,
	bool getFullDigestInfo
)
```

[`VB.NET`]

```
Public Shared Function DecodeDigestForSignature ( _
	data As Byte(), _
	getFullDigestInfo As Boolean _
) As Byte()
```

#### Parameters

data

:   Encoded message for signature

getFullDigestInfo

:   (optional) If true, extract the full DigestInfo; otherwise just extract the message digest itself

#### Return Value

Decoded data or an empty array on error

#### Remarks

Only EMSA-PKCS1-v1_5 is supported in this function.

#### See Also

VB6/C equivalent: [`RSA_DecodeMsg`](#RSA_DecodeMsg)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_DecodeMsgForEncryption"></a>Rsa.DecodeMsgForEncryption Method

 Decode a message for encryption. 

#### Syntax

[`C#`]

```
public static byte[] DecodeMsgForEncryption(
	byte[] data,
	Rsa.EME method
)
```

[`VB.NET`]

```
Public Shared Function DecodeMsgForEncryption ( _
	data As Byte(), _
	method As Rsa.EME _
) As Byte()
```

#### Parameters

data

:   Encoded message

method

:   Type: [Rsa.EME](#T_Rsa_EME)  

Encoding method used

#### Return Value

Decoded message

#### See Also

VB6/C equivalent: [`RSA_DecodeMsg`](#RSA_DecodeMsg)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_DecodeMsgIso9796"></a>Rsa.DecodeMsgIso9796 Method

 Decode a message padded using ISO/IEC 9796-1 formatting. 

#### Syntax

[`C#`]

```
public static byte[] DecodeMsgIso9796(
	byte[] data,
	int keyBits
)
```

[`VB.NET`]

```
Public Shared Function DecodeMsgIso9796 ( _
	data As Byte(), _
	keyBits As Integer _
) As Byte()
```

#### Parameters

data

:   encoded message for signature

keyBits

:   exact length of key in *bits*

#### Return Value

Recovered message or an empty array on error

#### See Also

VB6/C equivalent: [`RSA_DecodeMsg`](#RSA_DecodeMsg)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_Decrypt"></a>Rsa.Decrypt Method

 Decrypt a message encrypted using an RSA encryption scheme. 

#### Syntax

[`C#`]

```
public static byte[] Decrypt(
	byte[] data,
	string privateKeyFile,
	string password,
	Rsa.EME method,
	Rsa.HashAlg hashAlg,
	Rsa.AdvOptions advOpts
)
```

[`VB.NET`]

```
Public Shared Function Decrypt ( _
	data As Byte(), _
	privateKeyFile As String, _
	password As String, _
	method As Rsa.EME, _
	hashAlg As Rsa.HashAlg, _
	advOpts As Rsa.AdvOptions _
) As Byte()
```

#### Parameters

data

:   Data to be decrypted (*must* be exactly the same length as the key modulus size).

privateKeyFile

:   Name of the private key file, or a string containing the key in PEM format, or a valid internal private key string.

password

:   Password for encrypted private key, or "" if password is not required.

method

:   Type: [Rsa.EME](#T_Rsa_EME)  

Encoding method [optional, default = EME.PKCSv1_5]

hashAlg

:   Type: [Rsa.HashAlg](#T_Rsa_HashAlg)  

Hash function for EME-OAEP encoding, otherwise ignored.

advOpts

:   Type: [Rsa.AdvOptions](#T_Rsa_AdvOptions)  

Advanced options for EME-OEAP only.

#### Return Value

Decrypted data.

#### Remarks

For RSA-OAEP you must set the correct options to match the parameters used for the encryption.

#### See Also

VB6/C equivalent: [`RSA_Decrypt`](#RSA_Decrypt)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_EncodeDigestForSignature"></a>Rsa.EncodeDigestForSignature Method

 Encode a message digest for signature. 

#### Syntax

[`C#`]

```
public static byte[] EncodeDigestForSignature(
	int keyBytes,
	byte[] digest,
	HashAlgorithm hashAlg
)
```

[`VB.NET`]

```
Public Shared Function EncodeDigestForSignature ( _
	keyBytes As Integer, _
	digest As Byte(), _
	hashAlg As HashAlgorithm _
) As Byte()
```

#### Parameters

keyBytes

:   Number of bytes in the key

digest

:   Digest of message

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Message digest algorithm used to create digest

#### Return Value

Encoded block

#### Remarks

Only EMSA-PKCS1-v1_5 is supported in this function.

#### See Also

VB6/C equivalent: [`RSA_EncodeMsg`](#RSA_EncodeMsg)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_EncodeMsgForEncryption"></a>Rsa.EncodeMsgForEncryption Method

 Encode a message for encryption. 

#### Syntax

[`C#`]

```
public static byte[] EncodeMsgForEncryption(
	int keyBytes,
	byte[] message,
	Rsa.EME method
)
```

[`VB.NET`]

```
Public Shared Function EncodeMsgForEncryption ( _
	keyBytes As Integer, _
	message As Byte(), _
	method As Rsa.EME _
) As Byte()
```

#### Parameters

keyBytes

:   Number of bytes in the key

message

:   Message to be encoded

method

:   Type: [Rsa.EME](#T_Rsa_EME)  

Encoding method to use

#### Return Value

Encoded message block

#### See Also

VB6/C equivalent: [`RSA_EncodeMsg`](#RSA_EncodeMsg)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_EncodeMsgForSignature"></a>Rsa.EncodeMsgForSignature Method

 Encode a message for signature. 

#### Syntax

[`C#`]

```
public static byte[] EncodeMsgForSignature(
	int keyBytes,
	byte[] message,
	HashAlgorithm hashAlg
)
```

[`VB.NET`]

```
Public Shared Function EncodeMsgForSignature ( _
	keyBytes As Integer, _
	message As Byte(), _
	hashAlg As HashAlgorithm _
) As Byte()
```

#### Parameters

keyBytes

:   Number of bytes in the key

message

:   Message to be encoded

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Message digest algorithm to use

#### Return Value

Encoded block

#### Remarks

Only EMSA-PKCS1-v1_5 is supported in this function. Note we can only ever recover the *digest* from the encoded block.

#### See Also

VB6/C equivalent: [`RSA_EncodeMsg`](#RSA_EncodeMsg)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_EncodeMsgIso9796"></a>Rsa.EncodeMsgIso9796 Method

 Encode a message using ISO/IEC 9796-1 formatting. 

#### Syntax

[`C#`]

```
public static byte[] EncodeMsgIso9796(
	byte[] message,
	int keyBits
)
```

[`VB.NET`]

```
Public Shared Function EncodeMsgIso9796 ( _
	message As Byte(), _
	keyBits As Integer _
) As Byte()
```

#### Parameters

message

:   message to be encoded

keyBits

:   exact length of key in *bits*

#### Return Value

Padded message block ready for signing or an empty array on error

#### Remarks

The output block will be the same size as the key rounded up to the next whole byte. The message must be no longer than half the key length.

#### See Also

VB6/C equivalent: [`RSA_EncodeMsg`](#RSA_EncodeMsg)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_Encrypt"></a>Rsa.Encrypt Method

 Encrypt a short message using RSA encryption. 

#### Syntax

[`C#`]

```
public static byte[] Encrypt(
	byte[] data,
	string publicKeyFile,
	Rsa.EME method,
	Rsa.HashAlg hashAlg,
	Rsa.AdvOptions advOpts
)
```

[`VB.NET`]

```
Public Shared Function Encrypt ( _
	data As Byte(), _
	publicKeyFile As String, _
	method As Rsa.EME, _
	hashAlg As Rsa.HashAlg, _
	advOpts As Rsa.AdvOptions _
) As Byte()
```

#### Parameters

data

:   Data to be encrypted

publicKeyFile

:   Name of the public key file or X.509 certificate, or a string containing the key or certificate in PEM format, or a valid internal public key string.

method

:   Type: [Rsa.EME](#T_Rsa_EME)  

Encoding method [optional, default = EME.PKCSv1_5]

hashAlg

:   Type: [Rsa.HashAlg](#T_Rsa_HashAlg)  

Hash function for EME-OAEP encoding, otherwise ignored.

advOpts

:   Type: [Rsa.AdvOptions](#T_Rsa_AdvOptions)  

Advanced options for EME-OEAP only.

#### Return Value

Encrypted data or an empty array on error.

#### See Also

VB6/C equivalent: [`RSA_Encrypt`](#RSA_Encrypt)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_FromXMLString_String"></a>Rsa.FromXMLString Method (String)

 Create an RSA key string in internal format from an XML string. 

#### Syntax

[`C#`]

```
public static string FromXMLString(
	string xmlString
)
```

[`VB.NET`]

```
Public Shared Function FromXMLString ( _
	xmlString As String _
) As String
```

#### Parameters

xmlString

:   The XML string to use to reconstruct the RSA key

#### Return Value

Key string in internal format or empty string on error

#### Remarks

Creates an internal private key string if the XML contains private key parameters, otherwise an internal public key string.

#### See Also

VB6/C equivalent: [`RSA_FromXMLString`](#RSA_FromXMLString)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_FromXMLString_StringRsa_XmlOptions"></a>Rsa.FromXMLString Method (String, Rsa.XmlOptions)

 Create an RSA key string in internal format from an XML string with options. 

#### Syntax

[`C#`]

```
public static string FromXMLString(
	string xmlString,
	Rsa.XmlOptions options
)
```

[`VB.NET`]

```
Public Shared Function FromXMLString ( _
	xmlString As String, _
	options As Rsa.XmlOptions _
) As String
```

#### Parameters

xmlString

:   The XML string to use to reconstruct the RSA key

options

:   Type: [Rsa.XmlOptions](#T_Rsa_XmlOptions)  

Option flags: set as zero for defaults.

#### Return Value

Key string in internal format or empty string on error

#### See Also

VB6/C equivalent: [`RSA_FromXMLString`](#RSA_FromXMLString)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_FromXMLString_StringBoolean"></a>Rsa.FromXMLString Method (String, Boolean)

 Create an RSA key string in internal format from an XML string with flag to exclude private key details. 

#### Syntax

[`C#`]

```
public static string FromXMLString(
	string xmlString,
	bool excludePrivateParams
)
```

[`VB.NET`]

```
Public Shared Function FromXMLString ( _
	xmlString As String, _
	excludePrivateParams As Boolean _
) As String
```

#### Parameters

xmlString

:   The XML string to use to reconstruct the RSA key

excludePrivateParams

:   Reconstruct public key details only

#### Return Value

Key string in internal format or empty string on error

#### See Also

VB6/C equivalent: [`RSA_FromXMLString`](#RSA_FromXMLString)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_GetPrivateKeyFromPFX"></a>Rsa.GetPrivateKeyFromPFX Method

 Extract an encrypted private key from a PKCS-12 PKCS8ShroudedKeyBag, saving the output directly as a new file. 

#### Syntax

[`C#`]

```
public static int GetPrivateKeyFromPFX(
	string outputFile,
	string pfxFile
)
```

[`VB.NET`]

```
Public Shared Function GetPrivateKeyFromPFX ( _
	outputFile As String, _
	pfxFile As String _
) As Integer
```

#### Parameters

outputFile

:   Name of new file to create

pfxFile

:   PKCS-12 filename

#### Return Value

If successful, it returns the number of bytes written to the output file; otherwise it returns a negative [error code](#errorcodes)

#### See Also

VB6/C equivalent: [`RSA_GetPrivateKeyFromPFX`](#RSA_GetPrivateKeyFromPFX)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_GetPublicKeyFromCert"></a>Rsa.GetPublicKeyFromCert Method

 Read public key from X.509 certificate into internal string format. 

#### Syntax

[`C#`]

```
[ObsoleteAttribute("Use Rsa.ReadPublicKey() instead", false)]
public static StringBuilder GetPublicKeyFromCert(
	string certFile
)
```

[`VB.NET`]

```
<ObsoleteAttribute("Use Rsa.ReadPublicKey() instead", False)> _
Public Shared Function GetPublicKeyFromCert ( _
	certFile As String _
) As StringBuilder
```

#### Parameters

certFile

:   Filename of certificate file (or its base64 representation)

#### Return Value

StringBuilder containing an internal representation of the public key; or an empty StringBuilder if error

#### Remarks

This returns a StringBuilder, not a string. Use sb.ToString() to obtain a string.

#### See Also

VB6/C equivalent: [`RSA_GetPublicKeyFromCert`](#RSA_GetPublicKeyFromCert)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_KeyBits_String"></a>Rsa.KeyBits Method (String)

 Return number of significant bits in RSA key modulus. 

#### Syntax

[`C#`]

```
public static int KeyBits(
	string strRsaKey
)
```

[`VB.NET`]

```
Public Shared Function KeyBits ( _
	strRsaKey As String _
) As Integer
```

#### Parameters

strRsaKey

:   Internal key string

#### Return Value

Number of significant bits in key

#### See Also

VB6/C equivalent: [`RSA_KeyBits`](#RSA_KeyBits)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_KeyBits_StringBuilder"></a>Rsa.KeyBits Method (StringBuilder)

 Return number of significant bits in RSA key modulus. 

#### Syntax

[`C#`]

```
public static int KeyBits(
	StringBuilder sbRsaKey
)
```

[`VB.NET`]

```
Public Shared Function KeyBits ( _
	sbRsaKey As StringBuilder _
) As Integer
```

#### Parameters

sbRsaKey

:   Internal key string

#### Return Value

Number of significant bits in key

#### See Also

VB6/C equivalent: [`RSA_KeyBits`](#RSA_KeyBits)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_KeyBytes_String"></a>Rsa.KeyBytes Method (String)

 Return number of bytes (octets) in RSA key modulus. 

#### Syntax

[`C#`]

```
public static int KeyBytes(
	string strRsaKey
)
```

[`VB.NET`]

```
Public Shared Function KeyBytes ( _
	strRsaKey As String _
) As Integer
```

#### Parameters

strRsaKey

:   Internal key string

#### Return Value

Number of bytes in key

#### See Also

VB6/C equivalent: [`RSA_KeyBytes`](#RSA_KeyBytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_KeyBytes_StringBuilder"></a>Rsa.KeyBytes Method (StringBuilder)

 Return number of bytes (octets) in RSA key modulus. 

#### Syntax

[`C#`]

```
public static int KeyBytes(
	StringBuilder sbRsaKey
)
```

[`VB.NET`]

```
Public Shared Function KeyBytes ( _
	sbRsaKey As StringBuilder _
) As Integer
```

#### Parameters

sbRsaKey

:   Internal key string

#### Return Value

Number of bytes in key

#### See Also

VB6/C equivalent: [`RSA_KeyBytes`](#RSA_KeyBytes)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_KeyHashCode_String"></a>Rsa.KeyHashCode Method (String)

 Compute the hash code of an "internal" RSA public or private key string. 

#### Syntax

[`C#`]

```
public static int KeyHashCode(
	string intKeyString
)
```

[`VB.NET`]

```
Public Shared Function KeyHashCode ( _
	intKeyString As String _
) As Integer
```

#### Parameters

intKeyString

:   Internal key string

#### Return Value

A 32-bit hash code for the key, or zero on error.

#### Remarks

Should be the same for a matching private and public key.

#### See Also

VB6/C equivalent: [`RSA_KeyHashCode`](#RSA_KeyHashCode)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_KeyHashCode_StringBuilder"></a>Rsa.KeyHashCode Method (StringBuilder)

 Compute the hash code of an "internal" RSA public or private key string. 

#### Syntax

[`C#`]

```
public static int KeyHashCode(
	StringBuilder sbKeyString
)
```

[`VB.NET`]

```
Public Shared Function KeyHashCode ( _
	sbKeyString As StringBuilder _
) As Integer
```

#### Parameters

sbKeyString

:   Internal key string

#### Return Value

A 32-bit hash code for the key, or zero on error.

#### See Also

VB6/C equivalent: [`RSA_KeyHashCode`](#RSA_KeyHashCode)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_KeyMatch_StringString"></a>Rsa.KeyMatch Method (String, String)

 Verify that a pair of "internal" RSA private and public key strings are matched. 

#### Syntax

[`C#`]

```
public static int KeyMatch(
	string privateKey,
	string publicKey
)
```

[`VB.NET`]

```
Public Shared Function KeyMatch ( _
	privateKey As String, _
	publicKey As String _
) As Integer
```

#### Parameters

privateKey

:   Internal RSA private key string

publicKey

:   Internal RSA public key string

#### Return Value

0=valid key pair, or negative [error code](#errorcodes)

#### See Also

VB6/C equivalent: [`RSA_KeyMatch`](#RSA_KeyMatch)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_KeyMatch_StringBuilderStringBuilder"></a>Rsa.KeyMatch Method (StringBuilder, StringBuilder)

 Verify that a pair of "internal" RSA private and public key strings are matched. 

#### Syntax

[`C#`]

```
public static int KeyMatch(
	StringBuilder sbPrivateKey,
	StringBuilder sbPublicKey
)
```

[`VB.NET`]

```
Public Shared Function KeyMatch ( _
	sbPrivateKey As StringBuilder, _
	sbPublicKey As StringBuilder _
) As Integer
```

#### Parameters

sbPrivateKey

:   Internal RSA private key string

sbPublicKey

:   Internal RSA public key string

#### Return Value

0=valid key pair, or negative [error code](#errorcodes)

#### See Also

VB6/C equivalent: [`RSA_KeyMatch`](#RSA_KeyMatch)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_KeyValue"></a>Rsa.KeyValue Method

 Extract a base64-encoded RSA key value from internal key string 

#### Syntax

[`C#`]

```
public static string KeyValue(
	string keyString,
	string fieldName
)
```

[`VB.NET`]

```
Public Shared Function KeyValue ( _
	keyString As String, _
	fieldName As String _
) As String
```

#### Parameters

keyString

:   Public or private key in internal string format

fieldName

:   Name of field to be extracted: "Modulus" or "Exponent"

#### Return Value

Value encoded in base64 or an empty string on error

#### Remarks

The output is a continuous string of base64 characters suitable for a <RSAKeyValue> node in an XML-DSIG document.

#### See Also

VB6/C equivalent: [`RSA_KeyValue`](#RSA_KeyValue)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_MakeKeys_StringStringInt32Rsa_PublicExponentInt32StringCipherAlgorithmHashAlgorithmRsa_FormatBoolean"></a>Rsa.MakeKeys Method (String, String, Int32, Rsa.PublicExponent, Int32, String, CipherAlgorithm, HashAlgorithm, Rsa.Format, Boolean)

 Generate an RSA public/private key pair with extended options for encrypting private key [DEPRECATED]. 

#### Syntax

[`C#`]

```
[ObsoleteAttribute("Use Rsa.MakeKeys(String, String, String, Int32, Rsa.PublicExponent, Rsa.PbeOptions, String, Rsa.Format, Boolean) instead", 
	false)]
public static int MakeKeys(
	string publicKeyFile,
	string privateKeyFile,
	int bits,
	Rsa.PublicExponent exponent,
	int iterCount,
	string password,
	CipherAlgorithm cipherAlg,
	HashAlgorithm hashAlg,
	Rsa.Format fileFormat,
	bool showProgress
)
```

[`VB.NET`]

```
<ObsoleteAttribute("Use Rsa.MakeKeys(String, String, String, Int32, Rsa.PublicExponent, Rsa.PbeOptions, String, Rsa.Format, Boolean) instead",  _
	False)> _
Public Shared Function MakeKeys ( _
	publicKeyFile As String, _
	privateKeyFile As String, _
	bits As Integer, _
	exponent As Rsa.PublicExponent, _
	iterCount As Integer, _
	password As String, _
	cipherAlg As CipherAlgorithm, _
	hashAlg As HashAlgorithm, _
	fileFormat As Rsa.Format, _
	showProgress As Boolean _
) As Integer
```

#### Parameters

publicKeyFile

:   Output filename for public key

privateKeyFile

:   Output filename for (encrypted) private key

bits

:   Required key modulus size in bits (min 96)

exponent

:   Type: [Rsa.PublicExponent](#T_Rsa_PublicExponent)  

Exponent (Fermat Prime)

iterCount

:   Iteration count for encrypted private key

password

:   Password string for encrypted private key

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Block cipher to use for encryption scheme [default = des-ede3-cbc]

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash function to use in PRF HMAC algorithm [default = hmacWithSHA1]

fileFormat

:   Type: [Rsa.Format](#T_Rsa_Format)  

Format to save file [default = DER binary]

showProgress

:   Indicate progress in console

#### Return Value

Zero if successful or non-zero [error code](#errorcodes)

#### Remarks

The private key is saved in encrypted PKCS#8 format using the PBES2 encryption scheme from PKCS#5 with key derivation function PBKDF2.

#### See Also

VB6/C equivalent: [`RSA_MakeKeys`](#RSA_MakeKeys)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_MakeKeys_StringStringInt32Rsa_PublicExponentInt32StringRsa_PbeOptionsBooleanByte"></a>Rsa.MakeKeys Method (String, String, Int32, Rsa.PublicExponent, Int32, String, Rsa.PbeOptions, Boolean, Byte[])

 Generate an RSA public/private key pair [DEPRECATED]. 

#### Syntax

[`C#`]

```
[ObsoleteAttribute("Use Rsa.MakeKeys(String, String, String, Int32, Rsa.PublicExponent, Rsa.PbeOptions, String, Rsa.Format, Boolean) instead", 
	false)]
public static int MakeKeys(
	string publicKeyFile,
	string privateKeyFile,
	int bits,
	Rsa.PublicExponent exponent,
	int iterCount,
	string password,
	Rsa.PbeOptions cryptOption,
	bool showProgress,
	byte[] seedBytes
)
```

[`VB.NET`]

```
<ObsoleteAttribute("Use Rsa.MakeKeys(String, String, String, Int32, Rsa.PublicExponent, Rsa.PbeOptions, String, Rsa.Format, Boolean) instead",  _
	False)> _
Public Shared Function MakeKeys ( _
	publicKeyFile As String, _
	privateKeyFile As String, _
	bits As Integer, _
	exponent As Rsa.PublicExponent, _
	iterCount As Integer, _
	password As String, _
	cryptOption As Rsa.PbeOptions, _
	showProgress As Boolean, _
	seedBytes As Byte() _
) As Integer
```

#### Parameters

publicKeyFile

:   Output filename for public key

privateKeyFile

:   Output filename for (encrypted) private key

bits

:   Required key modulus size in bits (min 96)

exponent

:   Type: [Rsa.PublicExponent](#T_Rsa_PublicExponent)  

Exponent (Fermat Prime)

iterCount

:   Iteration count for encrypted private key

password

:   Password string for encrypted private key

cryptOption

:   Type: [Rsa.PbeOptions](#T_Rsa_PbeOptions)  

Option to specify encryption algorithm for private key

showProgress

:   Indicate progress in console

seedBytes

:   (optional) User-supplied-entropy in byte format

#### Return Value

Zero if successful or non-zero [error code](#errorcodes)

#### See Also

VB6/C equivalent: [`RSA_MakeKeys`](#RSA_MakeKeys)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_MakeKeys_StringStringStringInt32Rsa_PublicExponentRsa_PbeOptionsStringRsa_FormatBoolean"></a>Rsa.MakeKeys Method (String, String, String, Int32, Rsa.PublicExponent, Rsa.PbeOptions, String, Rsa.Format, Boolean)

 Generate an RSA public/private key pair. 

#### Syntax

[`C#`]

```
public static int MakeKeys(
	string publicKeyFile,
	string privateKeyFile,
	string password,
	int bits,
	Rsa.PublicExponent exponent,
	Rsa.PbeOptions pbes,
	string paramString,
	Rsa.Format fileFormat,
	bool showProgress
)
```

[`VB.NET`]

```
Public Shared Function MakeKeys ( _
	publicKeyFile As String, _
	privateKeyFile As String, _
	password As String, _
	bits As Integer, _
	exponent As Rsa.PublicExponent, _
	pbes As Rsa.PbeOptions, _
	paramString As String, _
	fileFormat As Rsa.Format, _
	showProgress As Boolean _
) As Integer
```

#### Parameters

publicKeyFile

:   Output filename for public key

privateKeyFile

:   Output filename for (encrypted) private key

password

:   Password for encrypted private key

bits

:   Required key modulus size in bits (min 96)

exponent

:   Type: [Rsa.PublicExponent](#T_Rsa_PublicExponent)  

Exponent [default=65537=F4]

pbes

:   Type: [Rsa.PbeOptions](#T_Rsa_PbeOptions)  

Encryption scheme to encrypt private key [default=pbeWithSHAAnd3-KeyTripleDES-CBC from PKCS#12]

paramString

:   Optional parameters. A set of attribute name=value pairs separated by a semicolon ";" (see remarks)

fileFormat

:   Type: [Rsa.Format](#T_Rsa_Format)  

Format to save file [default = DER binary]

showProgress

:   Indicate progress in console

#### Return Value

Zero if successful or non-zero [error code](#errorcodes)

#### Remarks

Valid name-value pairs for paramString are:

 

| **count**=integer | To set the iteration count used in the PBKDF2 method, e.g. "count=5000;" [default=2048]. |
| --- | --- |
| **prf**=hmac-name | To change the HMAC algorithm used in the PBKDF2 method, e.g. "prf=hmacwithSHA256;" [default=hmacwithSHA1]. |

 Valid values for hmac-name are {hmacWithSHA1|hmacWithSHA224|hmacWithSHA256|hmacWithSHA384|hmacWithSHA512}.

#### See Also

VB6/C equivalent: [`RSA_MakeKeysXtd`](#RSA_MakeKeysXtd)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_PublicKeyFromPrivate"></a>Rsa.PublicKeyFromPrivate Method

 Convert an internal private key string into a public one. 

#### Syntax

[`C#`]

```
public static StringBuilder PublicKeyFromPrivate(
	StringBuilder sbKeyString
)
```

[`VB.NET`]

```
Public Shared Function PublicKeyFromPrivate ( _
	sbKeyString As StringBuilder _
) As StringBuilder
```

#### Parameters

sbKeyString

:   StringBuilder containing private key in "internal" format

#### Return Value

StringBuilder containing an internal representation of the public key; or an empty StringBuilder if error

#### Remarks

This returns a StringBuilder, not a string. Use sb.ToString() to obtain a string.

#### See Also

VB6/C equivalent: [`RSA_PublicKeyFromPrivate`](#RSA_PublicKeyFromPrivate)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_RawPrivate_ByteString"></a>Rsa.RawPrivate Method (Byte[], String)

 Carry out RSA transformation using private key. 

#### Syntax

[`C#`]

```
public static byte[] RawPrivate(
	byte[] data,
	string privateKeyStr
)
```

[`VB.NET`]

```
Public Shared Function RawPrivate ( _
	data As Byte(), _
	privateKeyStr As String _
) As Byte()
```

#### Parameters

data

:   Data (**must** be same byte length as key modulus)

privateKeyStr

:   Private key in internal string format

#### Return Value

Transformed data

#### See Also

VB6/C equivalent: [`RSA_RawPrivate`](#RSA_RawPrivate)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_RawPrivate_ByteStringInt32"></a>Rsa.RawPrivate Method (Byte[], String, Int32)

 Carry out RSA transformation using private key (with specialist options). 

#### Syntax

[`C#`]

```
public static byte[] RawPrivate(
	byte[] data,
	string privateKeyStr,
	int options
)
```

[`VB.NET`]

```
Public Shared Function RawPrivate ( _
	data As Byte(), _
	privateKeyStr As String, _
	options As Integer _
) As Byte()
```

#### Parameters

data

:   Data (**must** be same byte length as key modulus)

privateKeyStr

:   Private key in internal string format

options

:   Specialist options value

#### Return Value

Transformed data

#### See Also

VB6/C equivalent: [`RSA_RawPrivate`](#RSA_RawPrivate)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_RawPublic_ByteString"></a>Rsa.RawPublic Method (Byte[], String)

 Carry out RSA transformation using public key. 

#### Syntax

[`C#`]

```
public static byte[] RawPublic(
	byte[] data,
	string publicKeyStr
)
```

[`VB.NET`]

```
Public Shared Function RawPublic ( _
	data As Byte(), _
	publicKeyStr As String _
) As Byte()
```

#### Parameters

data

:   Data (**must** be same byte length as key modulus)

publicKeyStr

:   Public key in internal string format

#### Return Value

Transformed data

#### See Also

VB6/C equivalent: [`RSA_RawPublic`](#RSA_RawPublic)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_RawPublic_ByteStringInt32"></a>Rsa.RawPublic Method (Byte[], String, Int32)

 Carry out RSA transformation using public key (with specialist options). 

#### Syntax

[`C#`]

```
public static byte[] RawPublic(
	byte[] data,
	string publicKeyStr,
	int options
)
```

[`VB.NET`]

```
Public Shared Function RawPublic ( _
	data As Byte(), _
	publicKeyStr As String, _
	options As Integer _
) As Byte()
```

#### Parameters

data

:   Data (**must** be same byte length as key modulus)

publicKeyStr

:   Public key in internal string format

options

:   Specialist options value

#### Return Value

Transformed data

#### See Also

VB6/C equivalent: [`RSA_RawPublic`](#RSA_RawPublic)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_ReadEncPrivateKey"></a>Rsa.ReadEncPrivateKey Method

 Read encrypted private key file into internal string format. 

#### Syntax

[`C#`]

```
[ObsoleteAttribute("Use Rsa.ReadPrivateKey() instead", false)]
public static StringBuilder ReadEncPrivateKey(
	string privateKeyFile,
	string password
)
```

[`VB.NET`]

```
<ObsoleteAttribute("Use Rsa.ReadPrivateKey() instead", False)> _
Public Shared Function ReadEncPrivateKey ( _
	privateKeyFile As String, _
	password As String _
) As StringBuilder
```

#### Parameters

privateKeyFile

:   filename of a binary BER-encoded encrypted private key info file

password

:   password for key file

#### Return Value

StringBuilder containing an internal representation of the private key; or an empty StringBuilder if error

#### Remarks

This returns a StringBuilder, not a string. Use sb.ToString() to obtain a string.

#### See Also

VB6/C equivalent: [`RSA_ReadEncPrivateKey`](#RSA_ReadEncPrivateKey)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_ReadPrivateKey"></a>Rsa.ReadPrivateKey Method

 Read from a file or string containing a private key into an "internal" private key string. 

#### Syntax

[`C#`]

```
public static StringBuilder ReadPrivateKey(
	string privateKeyFile,
	string password
)
```

[`VB.NET`]

```
Public Shared Function ReadPrivateKey ( _
	privateKeyFile As String, _
	password As String _
) As StringBuilder
```

#### Parameters

privateKeyFile

:   Name of private key file or a PEM String containing the key

password

:   Password for private key, if encrypted

#### Return Value

StringBuilder containing an internal representation of the private key; or an empty StringBuilder if error

#### Remarks

This returns a StringBuilder, not a string, to allow secure wiping. Use sb.ToString() to obtain a string.

#### See Also

VB6/C equivalent: [`RSA_ReadAnyPrivateKey`](#RSA_ReadAnyPrivateKey)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_ReadPrivateKeyFromPFX"></a>Rsa.ReadPrivateKeyFromPFX Method

 Read a private key directly from an encrypted PFX/PKCS-12 file into an "internal" private key string. 

#### Syntax

[`C#`]

```
[ObsoleteAttribute("Use Rsa.ReadPrivateKey() instead", false)]
public static StringBuilder ReadPrivateKeyFromPFX(
	string pfxFile,
	string password
)
```

[`VB.NET`]

```
<ObsoleteAttribute("Use Rsa.ReadPrivateKey() instead", False)> _
Public Shared Function ReadPrivateKeyFromPFX ( _
	pfxFile As String, _
	password As String _
) As StringBuilder
```

#### Parameters

pfxFile

:   PKCS-12 filename

password

:   Password for PFX file

#### Return Value

StringBuilder containing an internal representation of the private key; or an empty StringBuilder if error

#### Remarks

This returns a StringBuilder, not a string. Use sb.ToString() to obtain a string.

#### See Also

VB6/C equivalent: [`RSA_ReadPrivateKeyFromPFX`](#RSA_ReadPrivateKeyFromPFX)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_ReadPrivateKeyInfo"></a>Rsa.ReadPrivateKeyInfo Method

 Read from an (unencrypted) PKCS-8 private key info file into a private key string. 

#### Syntax

[`C#`]

```
[ObsoleteAttribute("Use Rsa.ReadPrivateKey() instead", false)]
public static StringBuilder ReadPrivateKeyInfo(
	string prikeyinfoFile
)
```

[`VB.NET`]

```
<ObsoleteAttribute("Use Rsa.ReadPrivateKey() instead", False)> _
Public Shared Function ReadPrivateKeyInfo ( _
	prikeyinfoFile As String _
) As StringBuilder
```

#### Parameters

prikeyinfoFile

:   Name of file

#### Return Value

StringBuilder containing an internal representation of the private key; or an empty StringBuilder if error

#### Remarks

This returns a StringBuilder, not a string. Use sb.ToString() to obtain a string.

#### See Also

VB6/C equivalent: [`RSA_ReadPrivateKeyInfo`](#RSA_ReadPrivateKeyInfo)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_ReadPublicKey"></a>Rsa.ReadPublicKey Method

 Read from a file or string containing a public key into an "internal" public key string. 

#### Syntax

[`C#`]

```
public static StringBuilder ReadPublicKey(
	string certOrPublicKeyFile
)
```

[`VB.NET`]

```
Public Shared Function ReadPublicKey ( _
	certOrPublicKeyFile As String _
) As StringBuilder
```

#### Parameters

certOrPublicKeyFile

:   Name of X.509 certificate or public key file or a PEM String containing the key

#### Return Value

StringBuilder containing an internal representation of the public key; or an empty StringBuilder if error

#### Remarks

This returns a StringBuilder, not a string. Use sb.ToString() to obtain a string.

#### See Also

VB6/C equivalent: [`RSA_ReadPublicKey`](#RSA_ReadPublicKey)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_SaveEncKey"></a>Rsa.SaveEncKey Method

 Save an internal RSA key string to an encrypted key file. 

#### Syntax

[`C#`]

```
public static int SaveEncKey(
	string outputFile,
	string privateKey,
	string password,
	Rsa.PbeOptions pbeOption,
	string paramString,
	Rsa.Format format
)
```

[`VB.NET`]

```
Public Shared Function SaveEncKey ( _
	outputFile As String, _
	privateKey As String, _
	password As String, _
	pbeOption As Rsa.PbeOptions, _
	paramString As String, _
	format As Rsa.Format _
) As Integer
```

#### Parameters

outputFile

:   Name of output file to be created

privateKey

:   The private RSA key as an internal key string.

password

:   Password to be used for the encrypted key file.

pbeOption

:   Type: [Rsa.PbeOptions](#T_Rsa_PbeOptions)  

Encryption scheme to encrypt private key [default = pbeWithSHAAnd3-KeyTripleDES-CBC from PKCS#12]

paramString

:   Optional parameters. A set of attribute name=value pairs separated by a semicolon ";" (see remarks).

format

:   Type: [Rsa.Format](#T_Rsa_Format)  

File format

#### Return Value

If successful, the return value is zero; otherwise it returns a nonzero [error code](#errorcodes)

#### Remarks

Valid name-value pairs for paramString are:

 

| **count**=integer | To set the iteration count used in the PBKDF2 method, e.g. "count=5000;" [default=2048]. |
| --- | --- |
| **prf**=hmac-name | To change the HMAC algorithm used in the PBKDF2 method, e.g. "prf=hmacwithSHA256;" [default=hmacwithSHA1]. |

 Valid values for hmac-name are {hmacWithSHA1|hmacWithSHA224|hmacWithSHA256|hmacWithSHA384|hmacWithSHA512}.

#### See Also

VB6/C equivalent: [`RSA_SaveEncKey`](#RSA_SaveEncKey)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_SaveEncPrivateKey_StringStringInt32StringCipherAlgorithmHashAlgorithmRsa_Format"></a>Rsa.SaveEncPrivateKey Method (String, String, Int32, String, CipherAlgorithm, HashAlgorithm, Rsa.Format)

 Save a private key string to a PKCS-8 EncryptedPrivateKeyInfo file using PBES2 algorithm [DEPRECATED]. 

#### Syntax

[`C#`]

```
public static int SaveEncPrivateKey(
	string outputFile,
	string privateKey,
	int iterationCount,
	string password,
	CipherAlgorithm cipherAlg,
	HashAlgorithm hashAlg,
	Rsa.Format format
)
```

[`VB.NET`]

```
Public Shared Function SaveEncPrivateKey ( _
	outputFile As String, _
	privateKey As String, _
	iterationCount As Integer, _
	password As String, _
	cipherAlg As CipherAlgorithm, _
	hashAlg As HashAlgorithm, _
	format As Rsa.Format _
) As Integer
```

#### Parameters

outputFile

:   Name of file to create

privateKey

:   Private key in internal format

iterationCount

:   Iteration count to be used when encrypting file

password

:   Password string

cipherAlg

:   Type: [CipherAlgorithm](#T_CipherAlgorithm)  

Block cipher to use for encryption scheme [default = des-ede3-cbc]

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash function to use in PRF HMAC algorithm [default = hmacWithSHA1]

format

:   Type: [Rsa.Format](#T_Rsa_Format)  

File format

#### Return Value

If successful, the return value is zero; otherwise it returns a nonzero [error code](#errorcodes)

#### See Also

VB6/C equivalent: [`RSA_SaveEncPrivateKey`](#RSA_SaveEncPrivateKey)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_SaveEncPrivateKey_StringStringInt32StringRsa_PbeOptionsRsa_Format"></a>Rsa.SaveEncPrivateKey Method (String, String, Int32, String, Rsa.PbeOptions, Rsa.Format)

 Save a private key string to a PKCS-8 EncryptedPrivateKeyInfo file [DEPRECATED]. 

#### Syntax

[`C#`]

```
public static int SaveEncPrivateKey(
	string outputFile,
	string privateKey,
	int iterationCount,
	string password,
	Rsa.PbeOptions pbeOption,
	Rsa.Format format
)
```

[`VB.NET`]

```
Public Shared Function SaveEncPrivateKey ( _
	outputFile As String, _
	privateKey As String, _
	iterationCount As Integer, _
	password As String, _
	pbeOption As Rsa.PbeOptions, _
	format As Rsa.Format _
) As Integer
```

#### Parameters

outputFile

:   Name of file to create

privateKey

:   Private key in internal format

iterationCount

:   Iteration count to be used when encrypting file

password

:   Password string

pbeOption

:   Type: [Rsa.PbeOptions](#T_Rsa_PbeOptions)  

Type of password-based encryption to use [default = pbeWithSHAAnd3-KeyTripleDES-CBC]

format

:   Type: [Rsa.Format](#T_Rsa_Format)  

File format

#### Return Value

If successful, the return value is zero; otherwise it returns a nonzero [error code](#errorcodes)

#### See Also

VB6/C equivalent: [`RSA_SaveEncPrivateKey`](#RSA_SaveEncPrivateKey)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_SavePrivateKeyInfo"></a>Rsa.SavePrivateKeyInfo Method

 Save a private key string to an (unencrypted) PKCS-8 private key info file. 

#### Syntax

[`C#`]

```
public static int SavePrivateKeyInfo(
	string outputFile,
	string privateKey,
	Rsa.Format format
)
```

[`VB.NET`]

```
Public Shared Function SavePrivateKeyInfo ( _
	outputFile As String, _
	privateKey As String, _
	format As Rsa.Format _
) As Integer
```

#### Parameters

outputFile

:   Name of file to create

privateKey

:   Private key in internal format

format

:   Type: [Rsa.Format](#T_Rsa_Format)  

File format

#### Return Value

If successful, the return value is zero; otherwise it returns a nonzero [error code](#errorcodes)

#### Remarks

Do **not** use for a production key.

#### See Also

VB6/C equivalent: [`RSA_SavePrivateKeyInfo`](#RSA_SavePrivateKeyInfo)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_SavePublicKey"></a>Rsa.SavePublicKey Method

 Save a public key string to PKCS-1 public key file. 

#### Syntax

[`C#`]

```
public static int SavePublicKey(
	string outputFile,
	string publicKey,
	Rsa.Format format
)
```

[`VB.NET`]

```
Public Shared Function SavePublicKey ( _
	outputFile As String, _
	publicKey As String, _
	format As Rsa.Format _
) As Integer
```

#### Parameters

outputFile

:   Name of file to create

publicKey

:   Public key in internal format

format

:   Type: [Rsa.Format](#T_Rsa_Format)  

File format

#### Return Value

If successful, the return value is zero; otherwise it returns a nonzero [error code](#errorcodes)

#### See Also

VB6/C equivalent: [`RSA_SavePublicKey`](#RSA_SavePublicKey)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_ToXMLString_StringRsa_XmlOptions"></a>Rsa.ToXMLString Method (String, Rsa.XmlOptions)

 Create an XML string representation of an RSA internal key string. 

#### Syntax

[`C#`]

```
public static string ToXMLString(
	string intKeyString,
	Rsa.XmlOptions options
)
```

[`VB.NET`]

```
Public Shared Function ToXMLString ( _
	intKeyString As String, _
	options As Rsa.XmlOptions _
) As String
```

#### Parameters

intKeyString

:   Internal key string

options

:   Type: [Rsa.XmlOptions](#T_Rsa_XmlOptions)  

Option flags: set as zero for defaults.

#### Return Value

XML string or empty string on error

#### See Also

VB6/C equivalent: [`RSA_ToXMLString`](#RSA_ToXMLString)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Rsa_ToXMLString_StringStringRsa_XmlOptions"></a>Rsa.ToXMLString Method (String, String, Rsa.XmlOptions)

 Create an XML string representation of an RSA internal key string with option to add a namespace prefix. 

#### Syntax

[`C#`]

```
public static string ToXMLString(
	string intKeyString,
	string prefix,
	Rsa.XmlOptions options
)
```

[`VB.NET`]

```
Public Shared Function ToXMLString ( _
	intKeyString As String, _
	prefix As String, _
	options As Rsa.XmlOptions _
) As String
```

#### Parameters

intKeyString

:   Internal key string

prefix

:   Prefix to add to elements, e.g. "ds" or "ds:".

options

:   Type: [Rsa.XmlOptions](#T_Rsa_XmlOptions)  

Option flags: set as zero for defaults.

#### Return Value

XML string or empty string on error

#### Remarks

Use this extended function to add a namespace prefix to all elements in the XML output; for example, <ds:RSAKeyValue>. Note that it's up to the user to map the prefix to a URI somewhere in the final XML document.

#### See Also

VB6/C equivalent: [`RSA_ToXMLStringEx`](#RSA_ToXMLStringEx)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Sig_GetHashAlgFromSigAlg"></a>Sig.GetHashAlgFromSigAlg Method

 Get the hash algorithm used in the signature algorithm. 

#### Syntax

[`C#`]

```
public static HashAlgorithm GetHashAlgFromSigAlg(
	SigAlgorithm sigAlg
)
```

[`VB.NET`]

```
Public Shared Function GetHashAlgFromSigAlg ( _
	sigAlg As SigAlgorithm _
) As HashAlgorithm
```

#### Parameters

sigAlg

:   Type: [SigAlgorithm](#T_SigAlgorithm)  

Signature algorithm

#### Return Value

Hash algorithm used in sigAlg

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Sig_SignData"></a>Sig.SignData Method

 Compute a signature value over data in a byte array. 

#### Syntax

[`C#`]

```
public static string SignData(
	byte[] data,
	string privateKeyFile,
	string password,
	SigAlgorithm sigAlg,
	Sig.SigOptions sigOpts,
	Sig.Encoding sigEncoding
)
```

[`VB.NET`]

```
Public Shared Function SignData ( _
	data As Byte(), _
	privateKeyFile As String, _
	password As String, _
	sigAlg As SigAlgorithm, _
	sigOpts As Sig.SigOptions, _
	sigEncoding As Sig.Encoding _
) As String
```

#### Parameters

data

:   input data to be signed

privateKeyFile

:   Name of private key file (or a string containing the key in PEM format, or an internal private key)

password

:   Password for the private key, if encrypted

sigAlg

:   Type: [SigAlgorithm](#T_SigAlgorithm)  

Signature algorithm to be used

sigOpts

:   Type: [Sig.SigOptions](#T_Sig_SigOptions)  

(optional) Options for ECDSA and RSA-PSS signatures

sigEncoding

:   Type: [Sig.Encoding](#T_Sig_Encoding)  

Optional encodings for output [default=base64]

#### Return Value

The encoded signature, or an empty string on error

#### See Also

VB6/C equivalent: [`SIG_SignData`](#SIG_SignData)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Sig_SignDigest"></a>Sig.SignDigest Method

 Compute a signature value over a message digest value. 

#### Syntax

[`C#`]

```
public static string SignDigest(
	byte[] digest,
	string privateKeyFile,
	string password,
	SigAlgorithm sigAlg,
	Sig.SigOptions sigOpts,
	Sig.Encoding sigEncoding
)
```

[`VB.NET`]

```
Public Shared Function SignDigest ( _
	digest As Byte(), _
	privateKeyFile As String, _
	password As String, _
	sigAlg As SigAlgorithm, _
	sigOpts As Sig.SigOptions, _
	sigEncoding As Sig.Encoding _
) As String
```

#### Parameters

digest

:   digest value in a byte array

privateKeyFile

:   Name of private key file (or a string containing the key in PEM format, or an internal private key)

password

:   Password for the private key, if encrypted

sigAlg

:   Type: [SigAlgorithm](#T_SigAlgorithm)  

Signature algorithm to be used

sigOpts

:   Type: [Sig.SigOptions](#T_Sig_SigOptions)  

(optional) Options for ECDSA and RSA-PSS signatures

sigEncoding

:   Type: [Sig.Encoding](#T_Sig_Encoding)  

Optional encodings for output [default=base64]

#### Return Value

The encoded signature, or an empty string on error

#### See Also

VB6/C equivalent: [`SIG_SignData`](#SIG_SignData)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Sig_SignFile"></a>Sig.SignFile Method

 Compute a signature value over binary data in a file. 

#### Syntax

[`C#`]

```
public static string SignFile(
	string dataFile,
	string privateKeyFile,
	string password,
	SigAlgorithm sigAlg,
	Sig.SigOptions sigOpts,
	Sig.Encoding sigEncoding
)
```

[`VB.NET`]

```
Public Shared Function SignFile ( _
	dataFile As String, _
	privateKeyFile As String, _
	password As String, _
	sigAlg As SigAlgorithm, _
	sigOpts As Sig.SigOptions, _
	sigEncoding As Sig.Encoding _
) As String
```

#### Parameters

dataFile

:   Name of input file containing data to be signed

privateKeyFile

:   Name of private key file (or a string containing the key in PEM format, or an internal private key)

password

:   Password for the private key, if encrypted

sigAlg

:   Type: [SigAlgorithm](#T_SigAlgorithm)  

Signature algorithm to be used

sigOpts

:   Type: [Sig.SigOptions](#T_Sig_SigOptions)  

(optional) Options for ECDSA and RSA-PSS signatures

sigEncoding

:   Type: [Sig.Encoding](#T_Sig_Encoding)  

Optional encodings for output [default=base64]

#### Return Value

The encoded signature, or an empty string on error

#### See Also

VB6/C equivalent: [`SIG_SignFile`](#SIG_SignFile)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Sig_VerifyData"></a>Sig.VerifyData Method

 Verify a signature value over data in a byte array. 

#### Syntax

[`C#`]

```
public static int VerifyData(
	string sigStr,
	byte[] data,
	string certOrKeyFile,
	SigAlgorithm sigAlg,
	Sig.VerifyOpts opts
)
```

[`VB.NET`]

```
Public Shared Function VerifyData ( _
	sigStr As String, _
	data As Byte(), _
	certOrKeyFile As String, _
	sigAlg As SigAlgorithm, _
	opts As Sig.VerifyOpts _
) As Integer
```

#### Parameters

sigStr

:   Encoded signature value

data

:   Input data to be verified

certOrKeyFile

:   The X.509 certificate or public key file name (or a string containing the certificate or key in PEM format or base64 representation, or an internal key string).

sigAlg

:   Type: [SigAlgorithm](#T_SigAlgorithm)  

Signature algorithm used to create signature.

opts

:   Type: [Sig.VerifyOpts](#T_Sig_VerifyOpts)  

(optional) Advanced options for RSA-PSS only.

#### Return Value

Zero (0) if the signature is valid; otherwise a negative [error code](#errorcodes).

#### Remarks

Any valid encodings of the signature value are detected automatically.

#### See Also

VB6/C equivalent: [`SIG_VerifyData`](#SIG_VerifyData)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Sig_VerifyDigest"></a>Sig.VerifyDigest Method

 Verify a signature value over a message digest value of data. 

#### Syntax

[`C#`]

```
public static int VerifyDigest(
	string sigStr,
	byte[] digest,
	string certOrKeyFile,
	SigAlgorithm sigAlg,
	Sig.VerifyOpts opts
)
```

[`VB.NET`]

```
Public Shared Function VerifyDigest ( _
	sigStr As String, _
	digest As Byte(), _
	certOrKeyFile As String, _
	sigAlg As SigAlgorithm, _
	opts As Sig.VerifyOpts _
) As Integer
```

#### Parameters

sigStr

:   Containing the encoded signature value

digest

:   Byte array containing the message digest value of the data to be verified

certOrKeyFile

:   Specifying the X.509 certificate or public key file name (or a string containing the certificate or key in PEM format or base64 representation, or an internal key string).

sigAlg

:   Type: [SigAlgorithm](#T_SigAlgorithm)  

Signature algorithm used to create signature.

opts

:   Type: [Sig.VerifyOpts](#T_Sig_VerifyOpts)  

Advanced options for RSA-PSS only (optional)

#### Return Value

Zero (0) if the signature is valid; otherwise a negative [error code](#errorcodes).

#### Remarks

Any valid encodings of the signature value are detected automatically.

#### See Also

VB6/C equivalent: [`SIG_VerifyData`](#SIG_VerifyData)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Sig_VerifyFile"></a>Sig.VerifyFile Method

 Verify a signature value over data in a file. 

#### Syntax

[`C#`]

```
public static int VerifyFile(
	string sigStr,
	string dataFile,
	string certOrKeyFile,
	SigAlgorithm sigAlg,
	Sig.VerifyOpts opts
)
```

[`VB.NET`]

```
Public Shared Function VerifyFile ( _
	sigStr As String, _
	dataFile As String, _
	certOrKeyFile As String, _
	sigAlg As SigAlgorithm, _
	opts As Sig.VerifyOpts _
) As Integer
```

#### Parameters

sigStr

:   Containing the encoded signature value

dataFile

:   Name of file containing data to be verified

certOrKeyFile

:   Specifying the X.509 certificate or public key file name (or a string containing the certificate or key in PEM format or base64 representation, or an internal key string).

sigAlg

:   Type: [SigAlgorithm](#T_SigAlgorithm)  

Signature algorithm used to create signature.

opts

:   Type: [Sig.VerifyOpts](#T_Sig_VerifyOpts)  

Advanced options for RSA-PSS only (optional)

#### Return Value

Zero (0) if the signature is valid; otherwise a negative [error code](#errorcodes).

#### Remarks

Any valid encodings of the signature value are detected automatically.

#### See Also

VB6/C equivalent: [`SIG_VerifyFile`](#SIG_VerifyFile)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Smime_Extract"></a>Smime.Extract Method

 Extract the body from an S/MIME entity. 

#### Syntax

[`C#`]

```
public static int Extract(
	string outputFile,
	string inputFile,
	Smime.Options opts
)
```

[`VB.NET`]

```
Public Shared Function Extract ( _
	outputFile As String, _
	inputFile As String, _
	opts As Smime.Options _
) As Integer
```

#### Parameters

outputFile

:   Name of output file to be created

inputFile

:   Name of input file containing S/MIME entity

opts

:   Type: [Smime.Options](#T_Smime_Options)  

Options

#### Return Value

A positive number giving the size of the output file in bytes; otherwise it returns an [error code](#errorcodes)

#### Remarks

This is designed to extract the body from an S/MIME entity with a content type of application/pkcs7-mime with base64 or binary transfer encoding. In practice, it will extract the body from almost any type of S/MIME (or MIME) file, except one with quoted-printable transfer encoding. By default the output is encoded in binary. Use the EncodeBase64 option to encode the output in base64.

#### See Also

VB6/C equivalent: [`SMIME_Extract`](#SMIME_Extract)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Smime_Query"></a>Smime.Query Method

 Query an S/MIME entity for selected information. 

#### Syntax

[`C#`]

```
public static string Query(
	string inputFile,
	string query
)
```

[`VB.NET`]

```
Public Shared Function Query ( _
	inputFile As String, _
	query As String _
) As String
```

#### Parameters

inputFile

:   Name of file containing S/MIME entity

query

:   Query string (case insensitive)

#### Return Value

String containing the result or an empty string if not found or error.

#### Remarks

Valid queries are:

 

| "content-type" | Value of Content-Type, e.g. "application/pkcs7-mime". |
| --- | --- |
| "smime-type" | Value of smime-type parameter of Content-Type, e.g. , e.g. "enveloped-data". |
| "encoding" | Value of Content-Transfer-Encoding, e.g. "base64". |
| "name" | Value of name parameter of Content-Type, e.g. "smime.p7m" |
| "filename" | Value of filename parameter of Content-Disposition, e.g. "smime.p7m". |

#### See Also

VB6/C equivalent: [`SMIME_Query`](#SMIME_Query)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Smime_Wrap"></a>Smime.Wrap Method

 Wrap a CMS object in an S/MIME entity. 

#### Syntax

[`C#`]

```
public static int Wrap(
	string outputFile,
	string inputFile,
	Smime.Options opts
)
```

[`VB.NET`]

```
Public Shared Function Wrap ( _
	outputFile As String, _
	inputFile As String, _
	opts As Smime.Options _
) As Integer
```

#### Parameters

outputFile

:   Output file to be created

inputFile

:   Input file containing CMS object

opts

:   Type: [Smime.Options](#T_Smime_Options)  

Options

#### Return Value

A positive number giving the size of the output file in bytes; otherwise it returns an [error code](#errorcodes)

#### Remarks

The input file is expected to be a binary CMS object of type enveloped-data, signed-data or compressed-data; otherwise it is an error. The type of input file is detected automatically. By default the body is encoded in base64 encoding. Use the EncodeBinary option to encode the body in binary.

#### See Also

VB6/C equivalent: [`SMIME_Wrap`](#SMIME_Wrap)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Tdea_Decrypt_ByteByteModeByte"></a>Tdea.Decrypt Method (Byte[], Byte[], Mode, Byte[])

 Decrypt data in byte array. 

#### Syntax

[`C#`]

```
public static byte[] Decrypt(
	byte[] input,
	byte[] key,
	Mode mode,
	byte[] iv
)
```

[`VB.NET`]

```
Public Shared Function Decrypt ( _
	input As Byte(), _
	key As Byte(), _
	mode As Mode, _
	iv As Byte() _
) As Byte()
```

#### Parameters

input

:   Input data

key

:   Key of exactly 24 bytes (192 bits)

mode

:   Type: [Mode](#T_Mode)  

Cipher Mode

iv

:   IV of exactly 8 bytes or null for ECB mode

#### Return Value

Decrypted data in byte array or empty array on error

#### Remarks

For ECB and CBC modes, input data length **must** be an exact multiple of the block length

#### See Also

VB6/C equivalent: [`TDEA_BytesMode`](#TDEA_BytesMode)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Tdea_Decrypt_StringStringModeString"></a>Tdea.Decrypt Method (String, String, Mode, String)

 Decrypt hex-encoded data string. 

#### Syntax

[`C#`]

```
public static string Decrypt(
	string inputHex,
	string keyHex,
	Mode mode,
	string ivHex
)
```

[`VB.NET`]

```
Public Shared Function Decrypt ( _
	inputHex As String, _
	keyHex As String, _
	mode As Mode, _
	ivHex As String _
) As String
```

#### Parameters

inputHex

:   Hex-encoded input data

keyHex

:   Hex-encoded key representing exactly 24 bytes (192 bits)

mode

:   Type: [Mode](#T_Mode)  

Cipher Mode

ivHex

:   Hex-encoded IV representing exactly 8 bytes or "" for ECB mode

#### Return Value

Decrypted data in hex-encoded string or empty string on error

#### Remarks

For ECB and CBC modes, the length of the decoded input bytes **must** be an exact multiple of the block length

#### See Also

VB6/C equivalent: [`TDEA_HexMode`](#TDEA_HexMode)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Tdea_Decrypt_StringStringModeStringEncodingBase"></a>Tdea.Decrypt Method (String, String, Mode, String, EncodingBase)

 Decrypt encoded data string. 

#### Syntax

[`C#`]

```
public static string Decrypt(
	string inputStr,
	string keyStr,
	Mode mode,
	string ivStr,
	EncodingBase encodingBase
)
```

[`VB.NET`]

```
Public Shared Function Decrypt ( _
	inputStr As String, _
	keyStr As String, _
	mode As Mode, _
	ivStr As String, _
	encodingBase As EncodingBase _
) As String
```

#### Parameters

inputStr

:   Encoded input data

keyStr

:   Encoded key representing exactly 24 bytes (192 bits)

mode

:   Type: [Mode](#T_Mode)  

Cipher Mode

ivStr

:   Encoded IV representing exactly 8 bytes or "" for ECB mode

encodingBase

:   Type: [EncodingBase](#T_EncodingBase)  

Type of encoding used

#### Return Value

Decrypted data in encoded string or empty string on error

#### Remarks

For ECB and CBC modes, the length of the decoded input bytes **must** be an exact multiple of the block length

#### See Also

VB6/C equivalent: [`TDEA_B64Mode`](#TDEA_B64Mode)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Tdea_Encrypt_ByteByteModeByte"></a>Tdea.Encrypt Method (Byte[], Byte[], Mode, Byte[])

 Encrypt data in byte array. 

#### Syntax

[`C#`]

```
public static byte[] Encrypt(
	byte[] input,
	byte[] key,
	Mode mode,
	byte[] iv
)
```

[`VB.NET`]

```
Public Shared Function Encrypt ( _
	input As Byte(), _
	key As Byte(), _
	mode As Mode, _
	iv As Byte() _
) As Byte()
```

#### Parameters

input

:   Input data

key

:   Key of exactly 24 bytes (192 bits)

mode

:   Type: [Mode](#T_Mode)  

Cipher Mode

iv

:   IV of exactly 8 bytes or null for ECB mode

#### Return Value

Ciphertext in byte array or empty array on error

#### Remarks

For ECB and CBC modes, input data length **must** be an exact multiple of the block length

#### See Also

VB6/C equivalent: [`TDEA_BytesMode`](#TDEA_BytesMode)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Tdea_Encrypt_StringStringModeString"></a>Tdea.Encrypt Method (String, String, Mode, String)

 Encrypt hex-encoded data string. 

#### Syntax

[`C#`]

```
public static string Encrypt(
	string inputHex,
	string keyHex,
	Mode mode,
	string ivHex
)
```

[`VB.NET`]

```
Public Shared Function Encrypt ( _
	inputHex As String, _
	keyHex As String, _
	mode As Mode, _
	ivHex As String _
) As String
```

#### Parameters

inputHex

:   Hex-encoded input data

keyHex

:   Hex-encoded key representing exactly 24 bytes (192 bits)

mode

:   Type: [Mode](#T_Mode)  

Cipher Mode

ivHex

:   Hex-encoded IV representing exactly 8 bytes or "" for ECB mode

#### Return Value

Ciphertext in hex-encoded string or empty string on error

#### Remarks

For ECB and CBC modes, the length of the decoded input bytes **must** be an exact multiple of the block length

#### See Also

VB6/C equivalent: [`TDEA_HexMode`](#TDEA_HexMode)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Tdea_Encrypt_StringStringModeStringEncodingBase"></a>Tdea.Encrypt Method (String, String, Mode, String, EncodingBase)

 Encrypt encoded data string. 

#### Syntax

[`C#`]

```
public static string Encrypt(
	string inputStr,
	string keyStr,
	Mode mode,
	string ivStr,
	EncodingBase encodingBase
)
```

[`VB.NET`]

```
Public Shared Function Encrypt ( _
	inputStr As String, _
	keyStr As String, _
	mode As Mode, _
	ivStr As String, _
	encodingBase As EncodingBase _
) As String
```

#### Parameters

inputStr

:   Encoded input data

keyStr

:   Encoded key representing exactly 24 bytes (192 bits)

mode

:   Type: [Mode](#T_Mode)  

Cipher Mode

ivStr

:   Encoded IV representing exactly 8 bytes or "" for ECB mode

encodingBase

:   Type: [EncodingBase](#T_EncodingBase)  

Type of encoding used

#### Return Value

Ciphertext in hex-encoded string or empty string on error

#### Remarks

For ECB and CBC modes, the length of the decoded input bytes **must** be an exact multiple of the block length

#### See Also

VB6/C equivalent: [`TDEA_B64Mode`](#TDEA_B64Mode)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Tdea_FileDecrypt_StringStringByteModeByte"></a>Tdea.FileDecrypt Method (String, String, Byte[], Mode, Byte[])

 Decrypt a file. 

#### Syntax

[`C#`]

```
public static int FileDecrypt(
	string fileOut,
	string fileIn,
	byte[] key,
	Mode mode,
	byte[] iv
)
```

[`VB.NET`]

```
Public Shared Function FileDecrypt ( _
	fileOut As String, _
	fileIn As String, _
	key As Byte(), _
	mode As Mode, _
	iv As Byte() _
) As Integer
```

#### Parameters

fileOut

:   Name of output file to be created or overwritten

fileIn

:   Name of input file

key

:   Key of exactly 8 bytes (64 bits)

mode

:   Type: [Mode](#T_Mode)  

Cipher Mode

iv

:   IV of exactly 8 bytes or null for ECB mode

#### Return Value

0 if successful or non-zero [error code](#errorcodes)

#### Remarks

fileOut and fileIn must **not** be the same

#### See Also

VB6/C equivalent: [`TDEA_File`](#TDEA_File)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Tdea_FileDecrypt_StringStringStringModeString"></a>Tdea.FileDecrypt Method (String, String, String, Mode, String)

 Decrypt a file passing key and IV as hex strings. 

#### Syntax

[`C#`]

```
public static int FileDecrypt(
	string fileOut,
	string fileIn,
	string keyHex,
	Mode mode,
	string ivHex
)
```

[`VB.NET`]

```
Public Shared Function FileDecrypt ( _
	fileOut As String, _
	fileIn As String, _
	keyHex As String, _
	mode As Mode, _
	ivHex As String _
) As Integer
```

#### Parameters

fileOut

:   Name of output file to be created or overwritten

fileIn

:   Name of input file

keyHex

:   Hex-encoded key of exact length

mode

:   Type: [Mode](#T_Mode)  

Cipher Mode

ivHex

:   Hex-encoded IV or "" for ECB mode

#### Return Value

0 if successful or non-zero [error code](#errorcodes)

#### Remarks

fileOut and fileIn must **not** be the same. The output file is in binary format.

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Tdea_FileEncrypt_StringStringByteModeByte"></a>Tdea.FileEncrypt Method (String, String, Byte[], Mode, Byte[])

 Encrypt a file. 

#### Syntax

[`C#`]

```
public static int FileEncrypt(
	string fileOut,
	string fileIn,
	byte[] key,
	Mode mode,
	byte[] iv
)
```

[`VB.NET`]

```
Public Shared Function FileEncrypt ( _
	fileOut As String, _
	fileIn As String, _
	key As Byte(), _
	mode As Mode, _
	iv As Byte() _
) As Integer
```

#### Parameters

fileOut

:   Name of output file to be created or overwritten

fileIn

:   Name of input file

key

:   Key of exactly 24 bytes (192 bits)

mode

:   Type: [Mode](#T_Mode)  

Cipher Mode

iv

:   IV of exactly 8 bytes or null for ECB mode

#### Return Value

0 if successful or non-zero [error code](#errorcodes)

#### Remarks

fileOut and fileIn must **not** be the same

#### See Also

VB6/C equivalent: [`TDEA_File`](#TDEA_File)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Tdea_FileEncrypt_StringStringStringModeString"></a>Tdea.FileEncrypt Method (String, String, String, Mode, String)

 Encrypt a file passing key and IV as hex strings. 

#### Syntax

[`C#`]

```
public static int FileEncrypt(
	string fileOut,
	string fileIn,
	string keyHex,
	Mode mode,
	string ivHex
)
```

[`VB.NET`]

```
Public Shared Function FileEncrypt ( _
	fileOut As String, _
	fileIn As String, _
	keyHex As String, _
	mode As Mode, _
	ivHex As String _
) As Integer
```

#### Parameters

fileOut

:   Name of output file to be created or overwritten

fileIn

:   Name of input file

keyHex

:   Hex-encoded key of exact length

mode

:   Type: [Mode](#T_Mode)  

Cipher Mode

ivHex

:   Hex-encoded IV or "" for ECB mode

#### Return Value

0 if successful or non-zero [error code](#errorcodes)

#### Remarks

fileOut and fileIn must **not** be the same. The output file is in binary format.

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Wipe_Data"></a>Wipe.Data Method

 Zeroise data in memory. 

#### Syntax

[`C#`]

```
public static bool Data(
	byte[] data
)
```

[`VB.NET`]

```
Public Shared Function Data ( _
	data As Byte() _
) As Boolean
```

#### Parameters

data

:   data to be wiped

#### Return Value

true if successful; false if fails

#### See Also

VB6/C equivalent: [`WIPE_Data`](#WIPE_Data)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Wipe_File"></a>Wipe.File Method

 Securely wipe and delete a file with options. 

#### Syntax

[`C#`]

```
public static bool File(
	string fileName,
	Wipe.Options opts
)
```

[`VB.NET`]

```
Public Shared Function File ( _
	fileName As String, _
	opts As Wipe.Options _
) As Boolean
```

#### Parameters

fileName

:   Name of file to be wiped

opts

:   Type: [Wipe.Options](#T_Wipe_Options)  

Options (optional, default = DOD 7-pass)

#### Return Value

true if successful; false if fails

#### See Also

VB6/C equivalent: [`WIPE_File`](#WIPE_File)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Wipe_String"></a>Wipe.String Method

 Zeroise a StringBuilder. 

#### Syntax

[`C#`]

```
public static bool String(
	StringBuilder sb
)
```

[`VB.NET`]

```
Public Shared Function String ( _
	sb As StringBuilder _
) As Boolean
```

#### Parameters

sb

:   StringBuilder to be wiped

#### Return Value

true if successful; false if fails

#### Remarks

NB You can't wipe an ordinary string as they are immutable in C#, so store any sensitive string data in a StringBuilder.

#### See Also

VB6/C equivalent: [`WIPE_Data`](#WIPE_Data)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_CertExpiresOn"></a>X509.CertExpiresOn Method

 Return date and time certificate expires. 

#### Syntax

[`C#`]

```
public static string CertExpiresOn(
	string certFile
)
```

[`VB.NET`]

```
Public Shared Function CertExpiresOn ( _
	certFile As String _
) As String
```

#### Parameters

certFile

:   Filename of certificate file (or its base64 representation)

#### Return Value

Date and time in ISO format or Empty string if error

#### See Also

VB6/C equivalent: [`X509_CertExpiresOn`](#X509_CertExpiresOn)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_CertIssuedOn"></a>X509.CertIssuedOn Method

 Return date and time certificate was issued. 

#### Syntax

[`C#`]

```
public static string CertIssuedOn(
	string certFile
)
```

[`VB.NET`]

```
Public Shared Function CertIssuedOn ( _
	certFile As String _
) As String
```

#### Parameters

certFile

:   Filename of certificate file (or its base64 representation)

#### Return Value

Date and time in ISO format or Empty string if error

#### See Also

VB6/C equivalent: [`X509_CertIssuedOn`](#X509_CertIssuedOn)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_CertIssuerName"></a>X509.CertIssuerName Method

 Get the issuer name of an X.509 certificate. 

#### Syntax

[`C#`]

```
public static string CertIssuerName(
	string certFile,
	string delimiter
)
```

[`VB.NET`]

```
Public Shared Function CertIssuerName ( _
	certFile As String, _
	delimiter As String _
) As String
```

#### Parameters

certFile

:   Filename of certificate file (or its base64 representation)

delimiter

:   Optional character for delimiter [default = semicolon ";"]

#### Return Value

Issuer name or Empty string if error

#### Remarks

Use X509.QueryCert with query "issuerName" for more output options.

#### See Also

VB6/C equivalent: [`X509_CertIssuerName`](#X509_CertIssuerName)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_CertIsValidNow"></a>X509.CertIsValidNow Method

 Verify that an X.509 certificate is currently valid as per system clock. 

#### Syntax

[`C#`]

```
public static bool CertIsValidNow(
	string certFile
)
```

[`VB.NET`]

```
Public Shared Function CertIsValidNow ( _
	certFile As String _
) As Boolean
```

#### Parameters

certFile

:   Filename of certificate file (or its base64 representation)

#### Return Value

True if certificate is currently valid, otherwise false

#### See Also

VB6/C equivalent: [`X509_CertIsValidNow`](#X509_CertIsValidNow)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_CertRequest"></a>X509.CertRequest Method

 Create a PKCS #10 certificate signing request (CSR). 

#### Syntax

[`C#`]

```
public static int CertRequest(
	string reqFile,
	string privateKeyFile,
	string distName,
	string extensions,
	string password,
	SigAlgorithm sigAlg,
	X509.CsrOptions opts
)
```

[`VB.NET`]

```
Public Shared Function CertRequest ( _
	reqFile As String, _
	privateKeyFile As String, _
	distName As String, _
	extensions As String, _
	password As String, _
	sigAlg As SigAlgorithm, _
	opts As X509.CsrOptions _
) As Integer
```

#### Parameters

reqFile

:   Name of Certificate Signing Request file to be created

privateKeyFile

:   Name of subject's encrypted private key file

distName

:   Specifying the subject's distinguished name as a set of attribute key=value pairs separated with semi-colons (;). See Specifying Distinguished Names

extensions

:   A list of attribute-value pairs to be included in an extensionRequest field. See X.509 Extensions

password

:   password for Subject's encrypted private key file

sigAlg

:   Type: [SigAlgorithm](#T_SigAlgorithm)  

Signature algorithm (must match key type)

opts

:   Type: [X509.CsrOptions](#T_X509_CsrOptions)  

Option flags: set as zero for defaults.

#### Return Value

Zero if successful or a non-zero [error code](#errorcodes)

#### Remarks

An ECC key must use an ECDSA signature algorithm, and an RSA key must use an RSA signature algorithm.

#### See Also

VB6/C equivalent: [`X509_CertRequest`](#X509_CertRequest)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_CertSerialNumber"></a>X509.CertSerialNumber Method

 Return serial number in hex format. 

#### Syntax

[`C#`]

```
public static string CertSerialNumber(
	string certFile
)
```

[`VB.NET`]

```
Public Shared Function CertSerialNumber ( _
	certFile As String _
) As String
```

#### Parameters

certFile

:   Filename of certificate file (or its base64 representation)

#### Return Value

Serial number in hex format or Empty string if error

#### See Also

VB6/C equivalent: [`X509_CertSerialNumber`](#X509_CertSerialNumber)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_CertSubjectName"></a>X509.CertSubjectName Method

 Get the subject name of an X.509 certificate. 

#### Syntax

[`C#`]

```
public static string CertSubjectName(
	string certFile,
	string delimiter
)
```

[`VB.NET`]

```
Public Shared Function CertSubjectName ( _
	certFile As String, _
	delimiter As String _
) As String
```

#### Parameters

certFile

:   Filename of certificate file (or its base64 representation)

delimiter

:   Optional character for delimiter [default = semicolon ";"]

#### Return Value

Subject name or Empty string if error

#### Remarks

Use X509.QueryCert with query "subjectName" for more output options.

#### See Also

VB6/C equivalent: [`X509_CertSubjectName`](#X509_CertSubjectName)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_CertThumb"></a>X509.CertThumb Method

 Calculate the thumbprint (message digest hash) of an X.509 certificate. 

#### Syntax

[`C#`]

```
public static string CertThumb(
	string certFile,
	HashAlgorithm hashAlg
)
```

[`VB.NET`]

```
Public Shared Function CertThumb ( _
	certFile As String, _
	hashAlg As HashAlgorithm _
) As String
```

#### Parameters

certFile

:   Filename of certificate file (or its base64 representation)

hashAlg

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

HashAlgorithm

#### Return Value

String containing the message digest in hexadecimal format

#### See Also

VB6/C equivalent: [`X509_CertThumb`](#X509_CertThumb)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_CheckCertInCRL"></a>X509.CheckCertInCRL Method

 Check whether an X.509 certificate has been revoked in a Certificate Revocation List (CRL). 

#### Syntax

[`C#`]

```
public static int CheckCertInCRL(
	string certFile,
	string crlFile,
	string issuerCert,
	string dateStr
)
```

[`VB.NET`]

```
Public Shared Function CheckCertInCRL ( _
	certFile As String, _
	crlFile As String, _
	issuerCert As String, _
	dateStr As String _
) As Integer
```

#### Parameters

certFile

:   name of X.509 certificate to be checked (or base64 representation)

crlFile

:   name of CRL file

issuerCert

:   (optional) with name of X.509 certificate file for the entity that issued the CRL (or base64 representation)

dateStr

:   (optional) with date in ISO format (yyyy-mm-dd[Thh[:nn:ss]][Z]) on or after you wish to check for revocation. Leave empty ""  for any date. The time must be in GMT (UTC, Zulu time)

#### Return Value

Zero if the certificate is NOT in the CRL; X509.Revoked (REVOCATION_ERROR +42) if the certificate has been revoked; otherwise a nonzero [error code](#errorcodes).

#### Remarks

The optional dateStr parameter allows you check whether a certificate was revoked only after the given date-time, which must be GMT (UTC). If the optional issuerCert is specified, the signature of the CRL will be checked against the key in the issuer's certificate and a SIGNATURE_ERROR will result if the signature is invalid.

#### See Also

VB6/C equivalent: [`X509_CheckCertInCRL`](#X509_CheckCertInCRL)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_GetCertCountInP7Chain"></a>X509.GetCertCountInP7Chain Method

 Return number of certificates in a PKCS-7 "certs-only" certificate chain file. 

#### Syntax

[`C#`]

```
public static int GetCertCountInP7Chain(
	string inputFile
)
```

[`VB.NET`]

```
Public Shared Function GetCertCountInP7Chain ( _
	inputFile As String _
) As Integer
```

#### Parameters

inputFile

:   Name of the PKCS-7 "certs-only" file, or a string containing its PEM textual representation.

#### Return Value

Number of X.509 certificates found or a negative [error code](#errorcodes).

#### See Also

VB6/C equivalent: [`X509_GetCertCountInP7Chain`](#X509_GetCertCountInP7Chain)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_GetCertFromP7Chain"></a>X509.GetCertFromP7Chain Method

 Extract an X.509 certificate from a PKCS-7 "certs-only" certificate chain file, saving the output directly as a new file. 

#### Syntax

[`C#`]

```
public static int GetCertFromP7Chain(
	string outputFile,
	string inputFile,
	int index
)
```

[`VB.NET`]

```
Public Shared Function GetCertFromP7Chain ( _
	outputFile As String, _
	inputFile As String, _
	index As Integer _
) As Integer
```

#### Parameters

outputFile

:   Name of output file to be created

inputFile

:   Name of the PKCS-7 "certs-only" file, or a string containing its PEM textual representation.

index

:   specifying which certificate (1,2,...) in the chain to extract.

#### Return Value

If successful and index is greater than zero, it returns the number of bytes written to the output file, which may be zero if no certificate could be found at the given index. If an error occurred, it returns a negative [error code](#errorcodes).

#### Remarks

*[New in v12.2]* To find the number of certificates in the chain, use GetCertCountInP7Chain. The old (deprecated) way to find the count of certificates was to set index to zero.

#### See Also

VB6/C equivalent: [`X509_GetCertFromP7Chain`](#X509_GetCertFromP7Chain)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_GetCertFromPFX"></a>X509.GetCertFromPFX Method

 Extract an X.509 certificate from a PKCS-12 PFX/.p12 file, saving the output directly as a new file. 

#### Syntax

[`C#`]

```
public static int GetCertFromPFX(
	string outputFile,
	string inputFile,
	string password
)
```

[`VB.NET`]

```
Public Shared Function GetCertFromPFX ( _
	outputFile As String, _
	inputFile As String, _
	password As String _
) As Integer
```

#### Parameters

outputFile

:   Name of output file to be created

inputFile

:   Name of the PKCS-12 file, or a string containing its PEM textual representation.

password

:   Password or "" if not encrypted (default="")

#### Return Value

If successful, it returns the number of bytes written to the output file; otherwise it returns a negative [error code](#errorcodes)

#### Remarks

Only supports weak 40-bit RC2 encryption for the certificate.

#### See Also

VB6/C equivalent: [`X509_GetCertFromPFX`](#X509_GetCertFromPFX)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_GetP7ChainFromPFX"></a>X509.GetP7ChainFromPFX Method

 Extract all X.509 certificates from a PKCS-12 PFX/.p12 file, saving the output directly as a new PKCS-7 "certs-only" certificate chain file. 

#### Syntax

[`C#`]

```
public static int GetP7ChainFromPFX(
	string outputFile,
	string inputFile,
	string password
)
```

[`VB.NET`]

```
Public Shared Function GetP7ChainFromPFX ( _
	outputFile As String, _
	inputFile As String, _
	password As String _
) As Integer
```

#### Parameters

outputFile

:   Name of output file to be created

inputFile

:   Name of the PKCS-12 file, or a string containing its PEM textual representation.

password

:   Password or "" if not encrypted

#### Return Value

If successful, it returns the number of bytes written to the output file; otherwise it returns a negative [error code](#errorcodes)

#### Remarks

Only supports weak 40-bit RC2 encryption for the certificate.

#### See Also

VB6/C equivalent: [`X509_GetCertFromPFX`](#X509_GetCertFromPFX)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_HashIssuerAndSN"></a>X509.HashIssuerAndSN Method

 Create a message digest of the Issuer's name and the cert serial number. 

#### Syntax

[`C#`]

```
public static string HashIssuerAndSN(
	string certFile,
	HashAlgorithm algorithm
)
```

[`VB.NET`]

```
Public Shared Function HashIssuerAndSN ( _
	certFile As String, _
	algorithm As HashAlgorithm _
) As String
```

#### Parameters

certFile

:   Filename of certificate file (or its base64 representation)

algorithm

:   Type: [HashAlgorithm](#T_HashAlgorithm)  

Hash algorithm to use [default = SHA-1]

#### Return Value

Message digest in hex format or Empty string if error

#### Remarks

This (should) give a unique identifier for any certificate

#### See Also

VB6/C equivalent: [`X509_HashIssuerAndSN`](#X509_HashIssuerAndSN)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_KeyUsageFlags"></a>X509.KeyUsageFlags Method

 Returns a bitfield containing the keyUsage flags. 

#### Syntax

[`C#`]

```
public static int KeyUsageFlags(
	string certFile
)
```

[`VB.NET`]

```
Public Shared Function KeyUsageFlags ( _
	certFile As String _
) As Integer
```

#### Parameters

certFile

:   Filename of certificate file (or its base64 representation)

#### Return Value

If successful, it returns a positive integer containing the keyUsage flags; or 0 if no keyUsage flags are set; otherwise it returns a negative [error code](#errorcodes)

#### Remarks

See X509.KeyUsageOptions.

#### See Also

VB6/C equivalent: [`X509_KeyUsageFlags`](#X509_KeyUsageFlags)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_MakeCert"></a>X509.MakeCert Method

 Create a new X.509 certificate using subject's public key and issuer's private key files with signature options. 

#### Syntax

[`C#`]

```
public static int MakeCert(
	string certFile,
	string issuerCert,
	string subjectPubKeyFile,
	string issuerPriKeyFile,
	int certNum,
	int yearsValid,
	string distName,
	string extensions,
	X509.KeyUsageOptions keyUsageOptions,
	string password,
	SigAlgorithm sigAlg,
	X509.CertOptions options
)
```

[`VB.NET`]

```
Public Shared Function MakeCert ( _
	certFile As String, _
	issuerCert As String, _
	subjectPubKeyFile As String, _
	issuerPriKeyFile As String, _
	certNum As Integer, _
	yearsValid As Integer, _
	distName As String, _
	extensions As String, _
	keyUsageOptions As X509.KeyUsageOptions, _
	password As String, _
	sigAlg As SigAlgorithm, _
	options As X509.CertOptions _
) As Integer
```

#### Parameters

certFile

:   Name of file to be created

issuerCert

:   Name of issuer's certificate file

subjectPubKeyFile

:   File containing subjects public key data

issuerPriKeyFile

:   File containing issuer's private key data

certNum

:   Issue number for new certificate

yearsValid

:   How many years to be valid

distName

:   Distinguished name string. See Distinguished Names in the main manual.

extensions

:   Extensions: a list of attribute-value pairs separated by semicolons (;). See X.509 Extensions Parameter in the main manual.

keyUsageOptions

:   Type: [X509.KeyUsageOptions](#T_X509_KeyUsageOptions)  

Key usage options

password

:   For issuer's private key, if encrypted.

sigAlg

:   Type: [SigAlgorithm](#T_SigAlgorithm)  

Signature algorithm to sign certificate.

options

:   Type: [X509.CertOptions](#T_X509_CertOptions)  

Option flags: set as zero for defaults.

#### Return Value

Zero if successful or a non-zero [error code](#errorcodes)

#### Remarks

Valid extensions are: 

| **rfc822Name**=string; | To set the rfc822 email address in the subjectAltName extension, e.g. rfc822Name=myname@testorg.com. |
| --- | --- |
| **serialNumber**=hex-digits; | To override the serial number set by certNum with a larger, unlimited integer in hexadecimal format, e.g. serialNumber=12deadbeefcafe0123. |
| **subjectKeyIdentifier**=hex-digits; | To set the subjectAltName extension with an octet string (binary) value specified in hex format e.g. subjectKeyIdentifier=fedcba9876543210. |
| **notAfter**=iso-date-string; | To override the validity period set by yearsValid with a specific date and time in ISO format, e.g. notAfter=2020-12-31 or notAfter=2020-12-31T14:03:59. If no time is given it will default to 23:59:59. Note that this time is UTC (GMT) not local. |
| **notBefore**=iso-date-string; | To override the default start time from one minute ago to a specific date and time in ISO format, e.g. notBefore=2008-12-31. If no time is given it will default to 00:00:01. Note that this time is UTC (GMT) not local. |
| **<dotted-oid>**=#<hexstring>; | Add an arbitrary X.509 version 3 Extension with typeID set to decoded <dotted-oid> and extnValue set to ASN.1 value encoded in <hexstring>. |

 As an alternative, you can create a new X.509 certificate using a PKCS-10 certificate signing request (CSR) file. Pass the name of the CSR file in the subjectPubkeyFile parameter and set the distName empty "". The empty distinguished name parameter is a flag that a CSR file is being used.

#### See Also

VB6/C equivalent: [`X509_MakeCert`](#X509_MakeCert)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_MakeCertSelf"></a>X509.MakeCertSelf Method

 Create a self-signed X.509 certificate with signature options. 

#### Syntax

[`C#`]

```
public static int MakeCertSelf(
	string certFile,
	string privateKeyFile,
	int certNum,
	int yearsValid,
	string distName,
	string extensions,
	X509.KeyUsageOptions keyUsageOptions,
	string password,
	SigAlgorithm sigAlg,
	X509.CertOptions options
)
```

[`VB.NET`]

```
Public Shared Function MakeCertSelf ( _
	certFile As String, _
	privateKeyFile As String, _
	certNum As Integer, _
	yearsValid As Integer, _
	distName As String, _
	extensions As String, _
	keyUsageOptions As X509.KeyUsageOptions, _
	password As String, _
	sigAlg As SigAlgorithm, _
	options As X509.CertOptions _
) As Integer
```

#### Parameters

certFile

:   Name of file to be created

privateKeyFile

:   File containing issuer's private key data

certNum

:   Issue number for new certificate

yearsValid

:   How many years to be valid

distName

:   Distinguished name string. See Distinguished Names in the main manual.

extensions

:   Extensions: a list of attribute-value pairs separated by semicolons (;). See X.509 Extensions Parameter in the main manual.

keyUsageOptions

:   Type: [X509.KeyUsageOptions](#T_X509_KeyUsageOptions)  

Key usage options

password

:   For issuer's private key

sigAlg

:   Type: [SigAlgorithm](#T_SigAlgorithm)  

Signature algorithm to sign certificate.

options

:   Type: [X509.CertOptions](#T_X509_CertOptions)  

Option flags: set as zero for defaults.

#### Return Value

Zero if successful or a non-zero [error code](#errorcodes)

#### See Also

VB6/C equivalent: [`X509_MakeCertSelf`](#X509_MakeCertSelf)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_MakeCRL"></a>X509.MakeCRL Method

 Create an X.509 Certificate Revocation List (CRL). 

#### Syntax

[`C#`]

```
public static int MakeCRL(
	string crlFile,
	string issuerCert,
	string issuerKeyFile,
	string password,
	string revokedCertList,
	string extensions,
	SigAlgorithm sigAlg,
	X509.CrlOptions opts
)
```

[`VB.NET`]

```
Public Shared Function MakeCRL ( _
	crlFile As String, _
	issuerCert As String, _
	issuerKeyFile As String, _
	password As String, _
	revokedCertList As String, _
	extensions As String, _
	sigAlg As SigAlgorithm, _
	opts As X509.CrlOptions _
) As Integer
```

#### Parameters

crlFile

:   name of new CRL file to be created

issuerCert

:   name of issuer's X.509 certificate file (or base64 representation)

issuerKeyFile

:   name of issuer's encrypted private key file

password

:   password for Issuer's encrypted private key file

revokedCertList

:   list of revoked certificates in format serialNumber,revocationDate; ... or the empty string "" for no revoked certificates. See the Remarks section below for more details

extensions

:   A list of attribute-value pairs separated by semicolons (;) or the empty string "". Valid attribute-value pairs are:            

* lastUpdate=*iso-date-string*
* nextUpdate=*iso-date-string*

sigAlg

:   Type: [SigAlgorithm](#T_SigAlgorithm)  

Signature algorithm.

opts

:   Type: [X509.CrlOptions](#T_X509_CrlOptions)  

Options

#### Return Value

If successful, the return value is zero; otherwise it returns a non-zero [error code](#errorcodes).

#### Remarks

This creates a version 1 CRL file with no extensions or cRLReason's. The parameter revokedCertList must be in the form serialNumber,revocationDate;serialNumber,revocationDate; .... The serialNumber must either be a positive decimal integer (e.g. 123) or the number in hex format preceded by #x (e.g. #x0102deadbeef). The revocation date must be in ISO date format (e.g. 2009-12-31T12:59:59Z). For example, 

"1,2007-12-31; 2, 2009-12-31T12:59:59Z; 66000,2066-01-01; #x0102deadbeef,2010-02-28T01:01:59"

 By default, the lastUpdate time in the CRL is set to the time given by the system clock, and nextUpdate time is left empty. You can specify your own times using the lastUpdate and nextUpdate attributes in the extensions parameter. Times, if specified, must be in ISO 8601 format and are always interpreted as GMT times whether or not you add a "Z".

#### See Also

VB6/C equivalent: [`X509_MakeCRL`](#X509_MakeCRL)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_QueryCert"></a>X509.QueryCert Method

 Query an X.509 certificate file for selected information. 

#### Syntax

[`C#`]

```
public static string QueryCert(
	string certFile,
	string query,
	X509.OutputOpts outOpts
)
```

[`VB.NET`]

```
Public Shared Function QueryCert ( _
	certFile As String, _
	query As String, _
	outOpts As X509.OutputOpts _
) As String
```

#### Parameters

certFile

:   Filename of certificate file (or its base64 representation)

query

:   Query string (case insensitive)

outOpts

:   Type: [X509.OutputOpts](#T_X509_OutputOpts)  

Optional options for output (default = 0)

#### Return Value

String containing the result, or an empty string if query not found or on error.

#### Remarks

Both binary BER and PEM-format certificates can be read, as can a base64 representation of the certificate. 

Valid queries are:

| "version" | X.509 version number, e.g. "3". |
| --- | --- |
| "serialNumber" | Serial number in hex-encoded format. |
| "signatureAlgorithm" | Signature algorithm used, e.g. "sha1WithRSAEncryption". |
| "signatureValue" | Signature value in hex-encoded format. |
| "notBefore" | Date on which the certificate validity period begins in ISO format yyyy-mm-ddThh:nn:ssZ |
| "notAfter" | Date on which the certificate validity period ends in ISO format yyyy-mm-ddThh:nn:ssZ |
| "issuerName" | Distinguished name (DN) of entity who has signed and issued the certificate. |
| "subjectName" | Distinguished name (DN) of the subject. |
| "subjectPublicKeyAlgorithm" | Algorithm used in subject's public key, e.g. "dsa". |
| "subjectKeyIdentifier" | The subject key identifier extension, if present, in hex-encoded format. |
| "authorityKeyIdentifier" | The authority key identifier extension, if present, in hex-encoded format. |
| "rfc822Name" | Internet mail address contained in a subjectAltName extension, if present. |
| "isCA" | Returns "1" if the subject type is a CA, otherwise returns "0". |
| "keyUsageString" | keyUsage flags in text format, e.g. "digitalSignature,nonRepudiation". |
| "extKeyUsageString" | extKeyUsage purposes in text format, e.g. "codeSigning,timeStamping". |
| "cRLDistributionPointsURI" | First URI found in cRLDistributionPoints, if any. |
| "authorityInfoAccessURI" | First URI found in authorityInfoAccess, if any. |
| "subjectAltName" | Subject alternative name extension, if present. |
| "hashAlgorithm" | Hash algorithm used in signature, e.g. "sha256". |
| "pssParams" | Parameters used for RSA-PSS (if applicable). |

#### See Also

VB6/C equivalent: [`X509_QueryCert`](#X509_QueryCert)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_ReadCertStringFromP7Chain"></a>X509.ReadCertStringFromP7Chain Method

 Read an X.509 certificate into a base64 string from PKCS-7 "certs-only" data. 

#### Syntax

[`C#`]

```
public static string ReadCertStringFromP7Chain(
	string inputFile,
	int index
)
```

[`VB.NET`]

```
Public Shared Function ReadCertStringFromP7Chain ( _
	inputFile As String, _
	index As Integer _
) As String
```

#### Parameters

inputFile

:   filename of a PKCS-7 "certs-only" file, or a string containing its PEM textual representation.

index

:   specifying which certificate (1,2,...) in the chain to extract.

#### Return Value

String in continuous base64 format, or an empty string on error.

#### Remarks

*[New in v12.2]* To find the number of certificates in the chain, use GetCertCountInP7Chain. The old (deprecated) way to find the count of certificates was to set index to zero.

#### See Also

VB6/C equivalent: [`X509_ReadCertStringFromP7Chain`](#X509_ReadCertStringFromP7Chain)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_ReadCertStringFromPFX"></a>X509.ReadCertStringFromPFX Method

 Read an X.509 certificate into a base64 string from PKCS-12 PFX/.p12 data. 

#### Syntax

[`C#`]

```
public static string ReadCertStringFromPFX(
	string inputFile,
	string password
)
```

[`VB.NET`]

```
Public Shared Function ReadCertStringFromPFX ( _
	inputFile As String, _
	password As String _
) As String
```

#### Parameters

inputFile

:   filename of a PFX file, or a string containing its PEM textual representation.

password

:   password for PFX or "" if certificate is not encrypted

#### Return Value

String in continuous base64 format, or an empty string on error.

#### Remarks

Only supports weak 40-bit RC2 encryption for the certificate.

#### See Also

VB6/C equivalent: [`X509_ReadCertStringFromPFX`](#X509_ReadCertStringFromPFX)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_ReadStringFromFile"></a>X509.ReadStringFromFile Method

 Create a base64 string representation of a X.509 certificate file. 

#### Syntax

[`C#`]

```
public static string ReadStringFromFile(
	string certFile
)
```

[`VB.NET`]

```
Public Shared Function ReadStringFromFile ( _
	certFile As String _
) As String
```

#### Parameters

certFile

:   Filename of certificate file (or its base64 representation)

#### Return Value

String in continuous base64 format, or an empty string on error.

#### See Also

VB6/C equivalent: [`X509_ReadStringFromFile`](#X509_ReadStringFromFile)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_SaveFileFromString"></a>X509.SaveFileFromString Method

 Create a new X.509 certificate file from a base64 string representation. 

#### Syntax

[`C#`]

```
public static int SaveFileFromString(
	string newCertFile,
	string certString,
	bool inPEMFormat
)
```

[`VB.NET`]

```
Public Shared Function SaveFileFromString ( _
	newCertFile As String, _
	certString As String, _
	inPEMFormat As Boolean _
) As Integer
```

#### Parameters

newCertFile

:   Name of new certificate file to be created.

certString

:   String containing certificate data in base64 format.

inPEMFormat

:   True to save in base64 PEM format, or false to save in binary DER format.

#### Return Value

Zero if successful or non-zero [error code](#errorcodes)

#### Remarks

Any existing file of the same name will be overwritten without warning. 

A PEM format file will start with -----BEGIN CERTIFICATE-----.

#### See Also

VB6/C equivalent: [`X509_SaveFileFromString`](#X509_SaveFileFromString)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_TextDump"></a>X509.TextDump Method

 Dump details of an X.509 certificate or a X.509 certificate revocation list (CRL) or a PKCS-10 certificate signing request (CSR) to a text file. 

#### Syntax

[`C#`]

```
public static int TextDump(
	string outputFile,
	string certFile,
	X509.OutputOpts outOpts
)
```

[`VB.NET`]

```
Public Shared Function TextDump ( _
	outputFile As String, _
	certFile As String, _
	outOpts As X509.OutputOpts _
) As Integer
```

#### Parameters

outputFile

:   Filename of text file to be created

certFile

:   Filename of certificate file (or its base64 representation)

outOpts

:   Type: [X509.OutputOpts](#T_X509_OutputOpts)  

Options for output (optional)

#### Return Value

If successful, the return value is zero; otherwise it returns a nonzero [error code](#errorcodes).

#### Remarks

The notation [!] denotes a critical extension, e.g. Key Usage[!]:.

#### See Also

VB6/C equivalent: [`X509_TextDump`](#X509_TextDump)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_TextDumpToString"></a>X509.TextDumpToString Method

 Dump details of an X.509 certificate or a X.509 certificate revocation list (CRL) or a PKCS-10 certificate signing request (CSR) to a string. 

#### Syntax

[`C#`]

```
public static string TextDumpToString(
	string certFile,
	X509.OutputOpts outOpts
)
```

[`VB.NET`]

```
Public Shared Function TextDumpToString ( _
	certFile As String, _
	outOpts As X509.OutputOpts _
) As String
```

#### Parameters

certFile

:   Filename of certificate file (or its base64 representation)

outOpts

:   Type: [X509.OutputOpts](#T_X509_OutputOpts)  

Options for output

#### Return Value

String containing the result, or an empty string on error.

#### Remarks

The notation [!] denotes a critical extension, e.g. Key Usage[!]:.

#### See Also

VB6/C equivalent: [`X509_TextDumpToString`](#X509_TextDumpToString)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_ValidatePath"></a>X509.ValidatePath Method

 Validate a certificate path. 

#### Syntax

[`C#`]

```
public static int ValidatePath(
	string certListOrP7File,
	string trustedCert,
	bool noTimeCheck
)
```

[`VB.NET`]

```
Public Shared Function ValidatePath ( _
	certListOrP7File As String, _
	trustedCert As String, _
	noTimeCheck As Boolean _
) As Integer
```

#### Parameters

certListOrP7File

:   either a list of certificate names separated by a semicolon or the name of a PKCS-7 "certs-only" file containing the certificates to be validated

trustedCert

:   (optional) name of the trusted certificate (or base64 representation)

noTimeCheck

:   Set True to avoid checking if the certificates are valid now [default = check validity dates against system clock].

#### Return Value

Zero if the certification path is valid; X509.Invalid (CERT_PATH_ERROR +43) if the path is invalid; otherwise a negative [error code](#errorcodes).

#### See Also

VB6/C equivalent: [`X509_ValidatePath`](#X509_ValidatePath)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_X509_VerifyCert"></a>X509.VerifyCert Method

 Verify that an X.509 certificate has been signed by its issuer. 

#### Syntax

[`C#`]

```
public static int VerifyCert(
	string certToVerify,
	string issuerCert
)
```

[`VB.NET`]

```
Public Shared Function VerifyCert ( _
	certToVerify As String, _
	issuerCert As String _
) As Integer
```

#### Parameters

certToVerify

:   Filename of certificate to verify

issuerCert

:   Filename of purported issuer's certificate

#### Return Value

Zero if the certificate's signature is valid; X509.Failure (SIGNATURE_ERROR +22) if the validation fails; otherwise a positive [error code](#errorcodes).

#### Remarks

This can also be used to verify that an X.509 Certificate Revocation List (CRL) or PKCS#10 Certification Signing Request (CSR) has been signed by the owner of the issuer's certificate. Just pass the name of the file (or its base64/PEM string form) as certToVerify.

#### See Also

VB6/C equivalent: [`X509_VerifyCert`](#X509_VerifyCert)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="M_Xof_Bytes"></a>Xof.Bytes Method

 Generate bytes using an eXtendable-Output Function (XOF). 

#### Syntax

[`C#`]

```
public static byte[] Bytes(
	int numBytes,
	byte[] message,
	Xof.Alg xofAlg
)
```

[`VB.NET`]

```
Public Shared Function Bytes ( _
	numBytes As Integer, _
	message As Byte(), _
	xofAlg As Xof.Alg _
) As Byte()
```

#### Parameters

numBytes

:   Required number of output bytes.

message

:   Input message data.

xofAlg

:   Type: [Xof.Alg](#T_Xof_Alg)  

XOF algorithm.

#### Return Value

Output data in byte array.

#### See Also

VB6/C equivalent: [`XOF_Bytes`](#XOF_Bytes)

[[Contents](#topofpage)] [[Index](#index)]

---

<a id="dotnetenumerations"></a>Enumerations in .NET
---------------------------------------------------

* [AeadAlgorithm Enumeration](#T_AeadAlgorithm)
* [Asn1.Options Enumeration](#T_Asn1_Options)
* [Cipher.Opts Enumeration](#T_Cipher_Opts)
* [CipherAlgorithm Enumeration](#T_CipherAlgorithm)
* [Cms.ComprDataOptions Enumeration](#T_Cms_ComprDataOptions)
* [Cms.ContentEncrAlg Enumeration](#T_Cms_ContentEncrAlg)
* [Cms.EnvDataOptions Enumeration](#T_Cms_EnvDataOptions)
* [Cms.Format Enumeration](#T_Cms_Format)
* [Cms.KeyEncrAlgorithm Enumeration](#T_Cms_KeyEncrAlgorithm)
* [Cms.ReadOptions Enumeration](#T_Cms_ReadOptions)
* [Cms.SigAlg Enumeration](#T_Cms_SigAlg)
* [Cms.SigDataOptions Enumeration](#T_Cms_SigDataOptions)
* [Cnv.EncodingConversion Enumeration](#T_Cnv_EncodingConversion)
* [Cnv.EndianNess Enumeration](#T_Cnv_EndianNess)
* [Ecc.CurveName Enumeration](#T_Ecc_CurveName)
* [Ecc.Format Enumeration](#T_Ecc_Format)
* [Ecc.KeyType Enumeration](#T_Ecc_KeyType)
* [Ecc.PbeScheme Enumeration](#T_Ecc_PbeScheme)
* [EncodingBase Enumeration](#T_EncodingBase)
* [HashAlgorithm Enumeration](#T_HashAlgorithm)
* [Hpke.AeadAlg Enumeration](#T_Hpke_AeadAlg)
* [Hpke.CurveName Enumeration](#T_Hpke_CurveName)
* [Hpke.OutputOpts Enumeration](#T_Hpke_OutputOpts)
* [Kdf.HashAlg Enumeration](#T_Kdf_HashAlg)
* [Kdf.KdfAlg Enumeration](#T_Kdf_KdfAlg)
* [Kdf.KeyWrapAlg Enumeration](#T_Kdf_KeyWrapAlg)
* [Mode Enumeration](#T_Mode)
* [Padding Enumeration](#T_Padding)
* [Pfx.Options Enumeration](#T_Pfx_Options)
* [Prf.Alg Enumeration](#T_Prf_Alg)
* [Rng.Options Enumeration](#T_Rng_Options)
* [Rng.Strength Enumeration](#T_Rng_Strength)
* [Rsa.AdvOptions Enumeration](#T_Rsa_AdvOptions)
* [Rsa.EME Enumeration](#T_Rsa_EME)
* [Rsa.Format Enumeration](#T_Rsa_Format)
* [Rsa.HashAlg Enumeration](#T_Rsa_HashAlg)
* [Rsa.PbeOptions Enumeration](#T_Rsa_PbeOptions)
* [Rsa.PublicExponent Enumeration](#T_Rsa_PublicExponent)
* [Rsa.XmlOptions Enumeration](#T_Rsa_XmlOptions)
* [Sig.Encoding Enumeration](#T_Sig_Encoding)
* [Sig.SigOptions Enumeration](#T_Sig_SigOptions)
* [Sig.VerifyOpts Enumeration](#T_Sig_VerifyOpts)
* [SigAlgorithm Enumeration](#T_SigAlgorithm)
* [Smime.Options Enumeration](#T_Smime_Options)
* [Wipe.Options Enumeration](#T_Wipe_Options)
* [X509.CertOptions Enumeration](#T_X509_CertOptions)
* [X509.CrlOptions Enumeration](#T_X509_CrlOptions)
* [X509.CsrOptions Enumeration](#T_X509_CsrOptions)
* [X509.KeyUsageOptions Enumeration](#T_X509_KeyUsageOptions)
* [X509.OutputOpts Enumeration](#T_X509_OutputOpts)
* [Xof.Alg Enumeration](#T_Xof_Alg)

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_AeadAlgorithm"></a>AeadAlgorithm Enumeration

 Authenticated encryption algorithm. 

#### Syntax

[`C#`]

```
public enum AeadAlgorithm
```

[`VB.NET`]

```
Public Enumeration AeadAlgorithm
```

#### Members

|  | Member name | Description |
|  | Aes_128_Gcm | Use the AEAD_AES_128_GCM authenticated encryption algorithm from RFC 5116. |
|  | Aes_192_Gcm | Use the AES-192-GCM authenticated encryption algorithm in the same manner as RFC 5116. |
|  | Aes_256_Gcm | Use the AEAD_AES_256_GCM authenticated encryption algorithm from RFC 5116. |
|  | ChaCha20_Poly1305 | Use the AEAD_CHACHA20_POLY1305 authenticated encryption algorithm from RFC 8439. |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Asn1_Options"></a>Asn1.Options Enumeration

 Options for ASN.1 methods 

#### Syntax

[`C#`]

```
[FlagsAttribute]
public enum Options
```

[`VB.NET`]

```
<FlagsAttribute> _
Public Enumeration Options
```

#### Members

|  | Member name | Description |
|  | Default | Default options |
|  | NoComments | Hide the comments [default=show comments] |
|  | AddLevels | Show level numbers [default=hide level numbers] |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_CipherAlgorithm"></a>CipherAlgorithm Enumeration

 Block Cipher Algorithm 

#### Syntax

[`C#`]

```
public enum CipherAlgorithm
```

[`VB.NET`]

```
Public Enumeration CipherAlgorithm
```

#### Members

|  | Member name | Description |
|  | Tdea | Triple DES (TDEA, 3DES, des-ede3) |
|  | Aes128 | AES-128 |
|  | Aes192 | AES-192 |
|  | Aes256 | AES-256 |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Cipher_Opts"></a>Cipher.Opts Enumeration

 Advanced options 

#### Syntax

[`C#`]

```
[FlagsAttribute]
public enum Opts
```

[`VB.NET`]

```
<FlagsAttribute> _
Public Enumeration Opts
```

#### Members

|  | Member name | Description |
|  | Default | Default options |
|  | PrefixIV | Prefix (prepend) the IV before the ciphertext in the output (ignored for ECB mode) |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Cms_ComprDataOptions"></a>Cms.ComprDataOptions Enumeration

 Advanced options for CMS compressed-data objects 

#### Syntax

[`C#`]

```
[FlagsAttribute]
public enum ComprDataOptions
```

[`VB.NET`]

```
<FlagsAttribute> _
Public Enumeration ComprDataOptions
```

#### Members

|  | Member name | Description |
|  | Default | Default options. |
|  | NoInflate | Extract the compressed data as is without inflation. |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Cms_ContentEncrAlg"></a>Cms.ContentEncrAlg Enumeration

 Content encryption algorithm. 

#### Syntax

[`C#`]

```
public enum ContentEncrAlg
```

[`VB.NET`]

```
Public Enumeration ContentEncrAlg
```

#### Members

|  | Member name | Description |
|  | Default | Default = Triple DES *CAUTION!* |
|  | Tdea | Triple DES (TDEA, 3DES, des-ede3) |
|  | Aes128 | AES-128 |
|  | Aes192 | AES-192 |
|  | Aes256 | AES-256 |
|  | Aes_128_Gcm | AES-128-GCM authenticated encryption algorithm from RFC5116. |
|  | Aes_192_Gcm | AES-192-GCM authenticated encryption algorithm in the same manner as RFC5116. |
|  | Aes_256_Gcm | AES-256-GCM authenticated encryption algorithm from RFC5116. |
|  | ChaCha20_Poly1305 | AEAD_CHACHA20_POLY1305 authenticated encryption algorithm from RFC8439. |

#### Remarks

New in [v22.0]. Supersedes CipherAlgorithm parameter.

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Cms_EnvDataOptions"></a>Cms.EnvDataOptions Enumeration

 Advanced options for CMS enveloped-data objects. 

#### Syntax

[`C#`]

```
[FlagsAttribute]
public enum EnvDataOptions
```

[`VB.NET`]

```
<FlagsAttribute> _
Public Enumeration EnvDataOptions
```

#### Members

|  | Member name | Description |
|  | None | Default options. |
|  | FormatBase64 | Encode output in base64 (default = binary). |
|  | AltAlgId | Use alternative (non-standard) alternative TeleTrusT Content Encryption Algorithm Identifier. |
|  | BigFile | Use to speed up the encryption of large files (binary file to binary file only). |
|  | Mgf1Sha1 | Force the MGF1 hash function to be SHA-1 (RSA-OAEP only, default = same as encoding hash function). |
|  | Authenticated | Use AES-GCM authenticated encryption instead of AES-CBC (redundant as of [v22.0]). |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Cms_Format"></a>Cms.Format Enumeration

 Output format. 

#### Syntax

[`C#`]

```
public enum Format
```

[`VB.NET`]

```
Public Enumeration Format
```

#### Members

|  | Member name | Description |
|  | Default | Default output format |
|  | Binary | Binary output (default) |
|  | FormatBase64 | Output is encoded in base64 (default = binary). |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Cms_KeyEncrAlgorithm"></a>Cms.KeyEncrAlgorithm Enumeration

 Key encryption algorithm for key transport (ktri) technique 

#### Syntax

[`C#`]

```
public enum KeyEncrAlgorithm
```

[`VB.NET`]

```
Public Enumeration KeyEncrAlgorithm
```

#### Members

|  | Member name | Description |
|  | Default | Default |
|  | Rsa_Pkcs1v1_5 | RSAES-PKCS-v1_5 (rsaEncryption) |
|  | Rsa_Oaep | RSAES-OAEP |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Cms_ReadOptions"></a>Cms.ReadOptions Enumeration

 Options for reading CMS objects. 

#### Syntax

[`C#`]

```
[FlagsAttribute]
public enum ReadOptions
```

[`VB.NET`]

```
<FlagsAttribute> _
Public Enumeration ReadOptions
```

#### Members

|  | Member name | Description |
|  | None | Default options. |
|  | BigFile | Use to speed up the encryption of large files (binary file input only). |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Cms_SigAlg"></a>Cms.SigAlg Enumeration

 Signature algorithm for CMS signed-data objects. 

#### Syntax

[`C#`]

```
public enum SigAlg
```

[`VB.NET`]

```
Public Enumeration SigAlg
```

#### Members

|  | Member name | Description |
|  | Default | Use default signature algorithm (rsa-sha1/sha1WithRSAEncryption) |
|  | Rsa_Sha1 | Use sha1WithRSAEncryption (rsa-sha1) signature algorithm [default] |
|  | Rsa_Sha224 | Use sha224WithRSAEncryption (rsa-sha224) signature algorithm |
|  | Rsa_Sha256 | Use sha256WithRSAEncryption (rsa-sha256) signature algorithm |
|  | Rsa_Sha384 | Use sha384WithRSAEncryption (rsa-sha384) signature algorithm |
|  | Rsa_Sha512 | Use sha512WithRSAEncryption (rsa-sha512) signature algorithm |
|  | Rsa_Md5 | Use md5WithRSAEncryption (rsa-md5) signature algorithm [legacy, not recommended] |
|  | Rsa_Pss_Sha1 | Use RSA-PSS signature algorithm with SHA-1 |
|  | Rsa_Pss_Sha224 | Use RSA-PSS signature algorithm with SHA-224 |
|  | Rsa_Pss_Sha256 | Use RSA-PSS signature algorithm with SHA-256 |
|  | Rsa_Pss_Sha384 | Use RSA-PSS signature algorithm with SHA-384 |
|  | Rsa_Pss_Sha512 | Use RSA-PSS signature algorithm with SHA-512 |
|  | Ecdsa_Sha1 | Use ecdsaWithSHA1 (ecdsa-sha1) signature algorithm |
|  | Ecdsa_Sha224 | Use ecdsaWithSHA224 (ecdsa-sha224) signature algorithm |
|  | Ecdsa_Sha256 | Use ecdsaWithSHA256 (ecdsa-sha256) signature algorithm |
|  | Ecdsa_Sha384 | Use ecdsaWithSHA384 (ecdsa-sha384) signature algorithm |
|  | Ecdsa_Sha512 | Use ecdsaWithSHA512 (ecdsa-sha512) signature algorithm |
|  | Ed25519 | Use Ed25519 signature algorithm [RFC8032] |
|  | Ed448 | Use Ed448 signature algorithm [RFC8032 |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Cms_SigDataOptions"></a>Cms.SigDataOptions Enumeration

 Advanced options for CMS signed-data objects 

#### Syntax

[`C#`]

```
[FlagsAttribute]
public enum SigDataOptions
```

[`VB.NET`]

```
<FlagsAttribute> _
Public Enumeration SigDataOptions
```

#### Members

|  | Member name | Description |
|  | Default | Default option |
|  | ExcludeCerts | Exclude X.509 certs from output. |
|  | ExcludeData | Exclude data from output. |
|  | CertsOnly | Create a "certs-only" PKCS#7 certficate chain. |
|  | IncludeAttributes | To add signed attributes (default = no signed attributes) including content-type and message-digest plus any more added below. |
|  | AddSignTime | Add signing time to the signed attributes (requires IncludeAttributes). |
|  | AddSmimeCapabilities | Add S/MIME capabilities to the signed attributes (requires IncludeAttributes). |
|  | AddSigningCertificate | Add an ESS Signing Certificate attribute to the signed attributes (requires IncludeAttributes). |
|  | AddAlgProtection | Add an Algorithm Protection Attribute [RFC6211] to the signed attributes (requires IncludeAttributes). |
|  | FormatBase64 | Create output/expect input in base64 format (default = binary). |
|  | NoOuter | Create a "naked" SignedData object with no outerContentInfo as permitted by PKCS#7 v1.6 (specialist option). |
|  | AltAlgId | Use alternative (non-standard) signature algorithm identifiers, e.g. 'sha1withRSAEncryption' instead of 'rsaEncryption'. |
|  | BigFile | Use to speed up the processing of large files. |
|  | Mgf1Sha1 | Force the MGF1 hash function to be SHA-1 (RSASSA-PSS only, default = same as encoding hash function). |
|  | Pss_SaltLenZero | Use a zero-length salt in an RSA-PSS signature (default = hLen the length of the digest output). |
|  | PseudoSig | Create/sign a "pseudo" SignedData object with dummy placeholder signature. |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Cnv_EncodingConversion"></a>Cnv.EncodingConversion Enumeration

 Conversion directions for ByteEncoding. 

#### Syntax

[`C#`]

```
public enum EncodingConversion
```

[`VB.NET`]

```
Public Enumeration EncodingConversion
```

#### Members

|  | Member name | Description |
|  | Utf8_From_Latin1 | Converts UTF-8-encoded bytes into Latin-1-encoded |
|  | Latin1_From_Utf8 | Converts Latin-1-encoded bytes into UTF-8-encoded |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Cnv_EndianNess"></a>Cnv.EndianNess Enumeration

 Byte order. 

#### Syntax

[`C#`]

```
public enum EndianNess
```

[`VB.NET`]

```
Public Enumeration EndianNess
```

#### Members

|  | Member name | Description |
|  | BigEndian | Most-significant byte first |
|  | LittleEndian | Least-significant byte first |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Ecc_CurveName"></a>Ecc.CurveName Enumeration

 Supported curve names. 

#### Syntax

[`C#`]

```
public enum CurveName
```

[`VB.NET`]

```
Public Enumeration CurveName
```

#### Members

|  | Member name | Description |
|  | Secp192r1 | NIST curve P-192 |
|  | Secp224r1 | NIST curve P-224 |
|  | Secp256r1 | NIST curve P-256 |
|  | Secp384r1 | NIST curve P-384 |
|  | Secp521r1 | NIST curve P-521 |
|  | Secp256k1 | "Bitcoin" curve |
|  | P_192 | NIST curve P-192 (synonym for secp192r1) |
|  | P_224 | NIST curve P-256 (synonym for secp256r1) |
|  | P_256 | NIST curve P-224 (synonym for secp224r1) |
|  | P_384 | NIST curve P-384 (synonym for secp384r1) |
|  | P_521 | NIST curve P-521 (synonym for secp521r1) |
|  | Prime192v1 | Alternative name for NIST curve P-192 |
|  | Prime256v1 | Alternative name for NIST curve P-256 |
|  | BrainpoolP256r1 | ECC Brainpool curve [RFC5639] |
|  | BrainpoolP384r1 | ECC Brainpool curve [RFC5639] |
|  | BrainpoolP512r1 | ECC Brainpool curve [RFC5639] |
|  | Ed25519 | Safe curve for EdDSA |
|  | Ed448 | Safe curve for EdDSA |
|  | X25519 | Safe curve for ECDH |
|  | X448 | Safe curve for ECDH |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Ecc_Format"></a>Ecc.Format Enumeration

 Format for output files. 

#### Syntax

[`C#`]

```
public enum Format
```

[`VB.NET`]

```
Public Enumeration Format
```

#### Members

|  | Member name | Description |
|  | Default | Default = binary |
|  | Binary | Binary DER-encoded |
|  | PEM | PEM-encoded text file |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Ecc_KeyType"></a>Ecc.KeyType Enumeration

 Key type for unencrypted key file. 

#### Syntax

[`C#`]

```
public enum KeyType
```

[`VB.NET`]

```
Public Enumeration KeyType
```

#### Members

|  | Member name | Description |
|  | Default | Save key in the default format. |
|  | Pkcs8PrivateKeyInfo | Save a NIST/SEC curve private key in PKCS#8 PrivateKeyInfo format (ignored for a public key) |
|  | Legacy | Save a safe private key in "legacy" PKCS#8 v1 format (default is v2 OneAsymmetricKey) |
|  | PrivateKey | Key value represents a private key (use for reading safe curves) |
|  | PublicKey | Key value represents a public key (use for reading safe curves) |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Ecc_PbeScheme"></a>Ecc.PbeScheme Enumeration

 Password-based encryption scheme to encrypt the private key file. 

#### Syntax

[`C#`]

```
public enum PbeScheme
```

[`VB.NET`]

```
Public Enumeration PbeScheme
```

#### Members

|  | Member name | Description |
|  | Default | Default option (pbeWithSHAAnd3-KeyTripleDES-CBC) |
|  | PbeWithSHAAnd_KeyTripleDES_CBC | pbeWithSHAAnd3-KeyTripleDES-CBC from PKCS#12 |
|  | Pbe_Pbkdf2_des_EDE3_CBC | "pkcs5PBES2" with key derivation function "pkcs5PBKDF2" and encryption scheme "des-EDE3-CBC" |
|  | Pbe_Pbkdf2_aes128_CBC | "pkcs5PBES2" with key derivation function "pkcs5PBKDF2" and encryption scheme "aes128-CBC" |
|  | Pbe_Pbkdf2_aes192_CBC | "pkcs5PBES2" with key derivation function "pkcs5PBKDF2" and encryption scheme "aes192-CBC" |
|  | Pbe_Pbkdf2_aes256_CBC | "pkcs5PBES2" with key derivation function "pkcs5PBKDF2" and encryption scheme "aes256-CBC" |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_EncodingBase"></a>EncodingBase Enumeration

 Base for encoding methods 

#### Syntax

[`C#`]

```
public enum EncodingBase
```

[`VB.NET`]

```
Public Enumeration EncodingBase
```

#### Members

|  | Member name | Description |
|  | Base64 | Base64 encoding |
|  | Base16 | Base16 encoding (i.e. hexadecimal) |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_HashAlgorithm"></a>HashAlgorithm Enumeration

 Message Digest Hash Algorithm 

#### Syntax

[`C#`]

```
public enum HashAlgorithm
```

[`VB.NET`]

```
Public Enumeration HashAlgorithm
```

#### Members

|  | Member name | Description |
|  | Sha1 | SHA-1 (as per FIPS PUB 180-4) |
|  | Md5 | MD5 (as per RFC 1321) [legacy, not recommended] |
|  | Md2 | MD2 (as per RFC 1319) [legacy, definitely not recommended] |
|  | Sha224 | SHA-224 (as per FIPS PUB 180-4) |
|  | Sha256 | SHA-256 (as per FIPS PUB 180-4) |
|  | Sha384 | SHA-384 (as per FIPS PUB 180-4) |
|  | Sha512 | SHA-512 (as per FIPS PUB 180-4) |
|  | Sha3_224 | SHA-3-224 (as per FIPS PUB 202) |
|  | Sha3_256 | SHA-3-256 (as per FIPS PUB 202) |
|  | Sha3_384 | SHA-3-384 (as per FIPS PUB 202) |
|  | Sha3_512 | SHA-3-256 (as per FIPS PUB 202) |
|  | Ripemd160 | RIPEMD-160 |
|  | Bitcoin160 | RIPEMD-160 hash of a SHA-256 hash (RIPEMD160(SHA256(m))) |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Hpke_AeadAlg"></a>Hpke.AeadAlg Enumeration

 AEAD functions supported for HPKE 

#### Syntax

[`C#`]

```
public enum AeadAlg
```

[`VB.NET`]

```
Public Enumeration AeadAlg
```

#### Members

|  | Member name | Description |
|  | None | No AEAD algorithm. |
|  | Aes_128_Gcm | Use the AEAD_AES_128_GCM authenticated encryption algorithm from RFC5116. |
|  | Aes_256_Gcm | Use the AEAD_AES_256_GCM authenticated encryption algorithm from RFC5116. |
|  | ChaCha20_Poly1305 | Use the AEAD_CHACHA20_POLY1305 authenticated encryption algorithm from RFC8439. |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Hpke_CurveName"></a>Hpke.CurveName Enumeration

 Supported ECDH curves for HPKE 

#### Syntax

[`C#`]

```
public enum CurveName
```

[`VB.NET`]

```
Public Enumeration CurveName
```

#### Members

|  | Member name | Description |
|  | P_256 | NIST curve P-256 |
|  | P_384 | NIST curve P-384 |
|  | P_521 | NIST curve P-521 |
|  | X25519 | ECDH curve X25519 from RFC7748 |
|  | X448 | ECDH curve X448 from RFC7748 |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Hpke_OutputOpts"></a>Hpke.OutputOpts Enumeration

 Options to format or re-encode output. 

#### Syntax

[`C#`]

```
public enum OutputOpts
```

[`VB.NET`]

```
Public Enumeration OutputOpts
```

#### Members

|  | Member name | Description |
|  | Default | Default = output as ephemeral "internal" key string. |
|  | KeyAsHex | Output key in hex format compatible with test vectors in [RFC9180] |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Kdf_HashAlg"></a>Kdf.HashAlg Enumeration

 Hash algorithms for KDF 

#### Syntax

[`C#`]

```
public enum HashAlg
```

[`VB.NET`]

```
Public Enumeration HashAlg
```

#### Members

|  | Member name | Description |
|  | Sha1 | SHA-1 (as per FIPS PUB 180-4) |
|  | Sha224 | SHA-224 (as per FIPS PUB 180-4) |
|  | Sha256 | SHA-256 (as per FIPS PUB 180-4) |
|  | Sha384 | SHA-384 (as per FIPS PUB 180-4) |
|  | Sha512 | SHA-512 (as per FIPS PUB 180-4) |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Kdf_KdfAlg"></a>Kdf.KdfAlg Enumeration

 Key derivation functions 

#### Syntax

[`C#`]

```
public enum KdfAlg
```

[`VB.NET`]

```
Public Enumeration KdfAlg
```

#### Members

|  | Member name | Description |
|  | X963 | ANSI-X9.63-KDF key derivation function (default) |
|  | Hkdf | HMAC-based Key Derivation Function (HKDF) from [RFC5869] |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Kdf_KeyWrapAlg"></a>Kdf.KeyWrapAlg Enumeration

 Key wrap algorithms for KDF 

#### Syntax

[`C#`]

```
public enum KeyWrapAlg
```

[`VB.NET`]

```
Public Enumeration KeyWrapAlg
```

#### Members

|  | Member name | Description |
|  | Default | Default for Cms.MakeEnvData only. |
|  | Cms3DESwrap | Triple-DES Key Wrap algorithm from [RFC3217] |
|  | Aes128_wrap | AES-128 key wrap from [RFC3394] |
|  | Aes192_wrap | AES-192 key wrap from [RFC3394] |
|  | Aes256_wrap | AES-256 key wrap from [RFC3394] |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Mode"></a>Mode Enumeration

 Cipher Mode 

#### Syntax

[`C#`]

```
public enum Mode
```

[`VB.NET`]

```
Public Enumeration Mode
```

#### Members

|  | Member name | Description |
|  | ECB | Electronic Code Book mode |
|  | CBC | Cipher Block Chaining mode |
|  | OFB | Output Feedback mode |
|  | CFB | Cipher Feedback mode |
|  | CTR | Counter mode |
|  | GCM | Galois/Counter mode (AES only) |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Padding"></a>Padding Enumeration

 Block Cipher Padding 

#### Syntax

[`C#`]

```
public enum Padding
```

[`VB.NET`]

```
Public Enumeration Padding
```

#### Members

|  | Member name | Description |
|  | Default | Use default padding |
|  | NoPad | No padding is added |
|  | Pkcs5 | The padding scheme described in PKCS#5/#7 |
|  | OneAndZeroes | Pad with 0x80 followed by as many zero bytes necessary to fill the block |
|  | AnsiX923 | The padding scheme described in ANSI X9.23 |
|  | W3CPadding | The padding scheme described in W3C https://www.w3.org/TR/xmlenc-core1/#sec-Padding |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Pfx_Options"></a>Pfx.Options Enumeration

 Specialist options. 

#### Syntax

[`C#`]

```
[FlagsAttribute]
public enum Options
```

[`VB.NET`]

```
<FlagsAttribute> _
Public Enumeration Options
```

#### Members

|  | Member name | Description |
|  | Default | Default options: re-encrypt private key with "TripleDES-SHA1", encrypt certificate with 40-bit RC2, output in DER binary form. |
|  | PlainCert | Store the certificate in unencrypted form (default is encrypted with 40-bit RC2). |
|  | StrongCert | Encrypt the certificate with "stronger" TripleDES-SHA1 (default is "weak" 40-bit RC2). |
|  | CloneKey | Store the private key in the exact form of the pkcs-8 input file (default is to re-encrypt with Triple DES). |
|  | Aes256_Sha256 | Override other encryption options and encrypt both the private key and certificate using "AES256-SHA256" |
|  | DoubleEncrypt | Double-encrypt the private key (specialist option). |
|  | AltFormat | Create a PFX file with the exact peculiarities used by Microsoft (default is OpenSSL). |
|  | FormatPem | Create the output file in PEM format (default is DER-encoded binary). |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Prf_Alg"></a>Prf.Alg Enumeration

 Pseudorandom function (PRF) algorithm. 

#### Syntax

[`C#`]

```
public enum Alg
```

[`VB.NET`]

```
Public Enumeration Alg
```

#### Members

|  | Member name | Description |
|  | Kmac128 | KMAC128 as per NIST SP 800-185 |
|  | Kmac256 | KMAC256 as per NIST SP 800-185 |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Rng_Options"></a>Rng.Options Enumeration

 Rng options 

#### Syntax

[`C#`]

```
public enum Options
```

[`VB.NET`]

```
Public Enumeration Options
```

#### Members

|  | Member name | Description |
|  | Default | Default option |
|  | NoIntelDrng | Turn off support for INTEL(R) DRNG for the current session. |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Rng_Strength"></a>Rng.Strength Enumeration

 Required security strength for user-prompted entropy 

#### Syntax

[`C#`]

```
public enum Strength
```

[`VB.NET`]

```
Public Enumeration Strength
```

#### Members

|  | Member name | Description |
|  | Default | Default option |
|  | Bits_112 | 112 bits of security (default) |
|  | Bits_128 | 128 bits of security |
|  | Bits_192 | 192 bits of security |
|  | Bits_256 | 256 bits of security |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Rsa_AdvOptions"></a>Rsa.AdvOptions Enumeration

 Advanced options. 

#### Syntax

[`C#`]

```
[FlagsAttribute]
public enum AdvOptions
```

[`VB.NET`]

```
<FlagsAttribute> _
Public Enumeration AdvOptions
```

#### Members

|  | Member name | Description |
|  | Default | Default options. |
|  | Mgf1_Sha1 | Force the MGF hash function to be SHA-1 (OAEP only, default = same as encoding set by Rsa.HashAlg) |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Rsa_EME"></a>Rsa.EME Enumeration

 Encoding method for encryption. 

#### Syntax

[`C#`]

```
public enum EME
```

[`VB.NET`]

```
Public Enumeration EME
```

#### Members

|  | Member name | Description |
|  | PKCSv1_5 | EME-PKCS1-v1_5 encoding method |
|  | OAEP | EME-OAEP encoding method |

#### Remarks

See PKCS#1 v2.2 [RFC8017]

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Rsa_Format"></a>Rsa.Format Enumeration

 Format for saved RSA key. 

#### Syntax

[`C#`]

```
public enum Format
```

[`VB.NET`]

```
Public Enumeration Format
```

#### Members

|  | Member name | Description |
|  | Default | Default = Binary |
|  | Binary | Binary DER-encoded |
|  | PEM | PEM Format |
|  | SSL | PEM format compatible with OpenSSL |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Rsa_HashAlg"></a>Rsa.HashAlg Enumeration

 Hash function for OAEP encoding. 

#### Syntax

[`C#`]

```
public enum HashAlg
```

[`VB.NET`]

```
Public Enumeration HashAlg
```

#### Members

|  | Member name | Description |
|  | Sha1 | SHA-1 (default) |
|  | Sha224 | SHA-224 |
|  | Sha256 | SHA-256 |
|  | Sha384 | SHA-384 |
|  | Sha512 | SHA-512 |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Rsa_PbeOptions"></a>Rsa.PbeOptions Enumeration

 Password-based encryption scheme to be used to encrypt the private key file. 

#### Syntax

[`C#`]

```
public enum PbeOptions
```

[`VB.NET`]

```
Public Enumeration PbeOptions
```

#### Members

|  | Member name | Description |
|  | Default | Default option (pbeWithSHAAnd3-KeyTripleDES-CBC) |
|  | PbeWithSHAAnd_KeyTripleDES_CBC | pbeWithSHAAnd3-KeyTripleDES-CBC from PKCS#12 |
|  | Pbe_Pbkdf2_des_EDE3_CBC | "pkcs5PBES2" with key derivation function "pkcs5PBKDF2" and encryption scheme "des-EDE3-CBC" |
|  | Pbe_Pbkdf2_aes128_CBC | "pkcs5PBES2" with key derivation function "pkcs5PBKDF2" and encryption scheme "aes128-CBC" |
|  | Pbe_Pbkdf2_aes192_CBC | "pkcs5PBES2" with key derivation function "pkcs5PBKDF2" and encryption scheme "aes192-CBC" |
|  | Pbe_Pbkdf2_aes256_CBC | "pkcs5PBES2" with key derivation function "pkcs5PBKDF2" and encryption scheme "aes256-CBC" |
|  | PbeWithMD5AndDES_CBC | pbeWithMD5AndDES-CBC [legacy, not recommended for new implementations] |
|  | PbeWithMD2AndDES_CBC | pbeWithMD2AndDES-CBC [legacy, not recommended for new implementations] |
|  | PbeWithSHA1AndDES_CBC | pbeWithSHA1AndDES-CBC [legacy, not recommended for new implementations] |
|  | Pkcs5PBES2_des_EDE3_CBC | "pkcs5PBES2" with "pkcs5PBKDF2" and "des-EDE3-CBC" [Synonym retained for backwards compatibility] |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Rsa_PublicExponent"></a>Rsa.PublicExponent Enumeration

 Choices for public exponent (e) 

#### Syntax

[`C#`]

```
public enum PublicExponent
```

[`VB.NET`]

```
Public Enumeration PublicExponent
```

#### Members

|  | Member name | Description |
|  | Exp_EQ_3 | Set exponent equal to 3 (F0) |
|  | Exp_EQ_5 | Set exponent equal to 5 (F1) |
|  | Exp_EQ_17 | Set exponent equal to 17 (F2) |
|  | Exp_EQ_257 | Set exponent equal to 257 (F3) |
|  | Exp_EQ_65537 | Set exponent equal to 65537 (F4) |

#### Remarks

Fermat Number F(x) = 2^(2^x) + 1. F0 to F4 are prime.

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Rsa_XmlOptions"></a>Rsa.XmlOptions Enumeration

 Options when converting between internal RSA key and XML. 

#### Syntax

[`C#`]

```
[FlagsAttribute]
public enum XmlOptions
```

[`VB.NET`]

```
<FlagsAttribute> _
Public Enumeration XmlOptions
```

#### Members

|  | Member name | Description |
|  | ExcludePrivateParams | Exclude private key parameters |
|  | ForceRSAKeyValue | Create XML in .NET-compatible RSAKeyValue format (ToXML only) |
|  | HexBinaryFormat | Create XML in non-standard hex format (ToXML only) |
|  | RequirePrivate | Require private key to exist in the XML input or fail (FromXML only) |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_SigAlgorithm"></a>SigAlgorithm Enumeration

 Signature algorithm 

#### Syntax

[`C#`]

```
public enum SigAlgorithm
```

[`VB.NET`]

```
Public Enumeration SigAlgorithm
```

#### Members

|  | Member name | Description |
|  | Default | Use default signature algorithm [rsa-sha1/sha1WithRSAEncryption] |
|  | Rsa_Sha1 | Use sha1WithRSAEncryption (rsa-sha1) signature algorithm [default] |
|  | Rsa_Sha224 | Use sha224WithRSAEncryption (rsa-sha224) signature algorithm |
|  | Rsa_Sha256 | Use sha256WithRSAEncryption (rsa-sha256) signature algorithm |
|  | Rsa_Sha384 | Use sha384WithRSAEncryption (rsa-sha384) signature algorithm |
|  | Rsa_Sha512 | Use sha512WithRSAEncryption (rsa-sha512) signature algorithm |
|  | Rsa_Md5 | Use md5WithRSAEncryption (rsa-md5) signature algorithm [legacy, not recommended] |
|  | Rsa_Pss_Sha1 | Use RSA-PSS signature algorithm with SHA-1 |
|  | Rsa_Pss_Sha224 | Use RSA-PSS signature algorithm with SHA-224 |
|  | Rsa_Pss_Sha256 | Use RSA-PSS signature algorithm with SHA-256 |
|  | Rsa_Pss_Sha384 | Use RSA-PSS signature algorithm with SHA-384 |
|  | Rsa_Pss_Sha512 | Use RSA-PSS signature algorithm with SHA-512 |
|  | Ecdsa_Sha1 | Use ecdsaWithSHA1 (ecdsa-sha1) signature algorithm |
|  | Ecdsa_Sha224 | Use ecdsaWithSHA224 (ecdsa-sha224) signature algorithm |
|  | Ecdsa_Sha256 | Use ecdsaWithSHA256 (ecdsa-sha256) signature algorithm |
|  | Ecdsa_Sha384 | Use ecdsaWithSHA384 (ecdsa-sha384) signature algorithm |
|  | Ecdsa_Sha512 | Use ecdsaWithSHA512 (ecdsa-sha512) signature algorithm |
|  | Ed25519 | Use Ed25519 signature algorithm |
|  | Ed448 | Use Ed448 signature algorithm |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Sig_Encoding"></a>Sig.Encoding Enumeration

 Encodings for signature output. 

#### Syntax

[`C#`]

```
public enum Encoding
```

[`VB.NET`]

```
Public Enumeration Encoding
```

#### Members

|  | Member name | Description |
|  | Default | Default encoding (base64) |
|  | Base64 | Base64 encoding (default) |
|  | Base64url | URL-safe base64 encoding as in section 5 of [RFC4648] |
|  | Base16 | Base16 encoding (i.e. hexadecimal) |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Sig_SigOptions"></a>Sig.SigOptions Enumeration

 Specialist options for signatures. 

#### Syntax

[`C#`]

```
[FlagsAttribute]
public enum SigOptions
```

[`VB.NET`]

```
<FlagsAttribute> _
Public Enumeration SigOptions
```

#### Members

|  | Member name | Description |
|  | Default | Use default options for signature. |
|  | UseDeterministic | ECDSA only: Use the deterministic digital signature generation procedure of [RFC6979] for ECDSA signature [default=random k]. |
|  | Asn1DERStructure | ECDSA only: Form ECDSA signature value as a DER-encoded ASN.1 structure [default=r||s]. |
|  | PssSaltLenHlen | RSA-PSS only: Set the salt length to hLen, the length of the output of the hash function [default]. |
|  | PssSaltLenMax | RSA-PSS only: Set the salt length to the maximum possible (like OpenSSL). |
|  | PssSaltLen20 | RSA-PSS only: Set the salt length to be exactly 20 bytes regardless of the hash algorithm. |
|  | PssSaltLenZero | RSA-PSS only: Set the salt length to be zero. |
|  | Mgf1Sha1 | RSA-PSS only: Force the MGF hash function to be SHA-1 [default = same as signature hash algorithm] |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Sig_VerifyOpts"></a>Sig.VerifyOpts Enumeration

 Specialist options for verifying a signature. 

#### Syntax

[`C#`]

```
[FlagsAttribute]
public enum VerifyOpts
```

[`VB.NET`]

```
<FlagsAttribute> _
Public Enumeration VerifyOpts
```

#### Members

|  | Member name | Description |
|  | Default | Use default options. |
|  | Mgf1Sha1 | RSA-PSS only: Force the MGF hash function to be SHA-1 [default = same as signature hash algorithm] |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Smime_Options"></a>Smime.Options Enumeration

 Options for S/MIME methods 

#### Syntax

[`C#`]

```
[FlagsAttribute]
public enum Options
```

[`VB.NET`]

```
<FlagsAttribute> _
Public Enumeration Options
```

#### Members

|  | Member name | Description |
|  | Default | Default options |
|  | EncodeBase64 | Encode output in base64 |
|  | EncodeBinary | Encode body in binary encoding |
|  | AddX | Add an "x-" to the content subtype (for compatibility with legacy applications) |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Wipe_Options"></a>Wipe.Options Enumeration

 Wipe options. 

#### Syntax

[`C#`]

```
public enum Options
```

[`VB.NET`]

```
Public Enumeration Options
```

#### Members

|  | Member name | Description |
|  | Default | Default options (DOD 7-pass) |
|  | Dod7Pass | DOD 7-pass (default) |
|  | Simple | Overwrite with single pass of zero bytes (quicker but less secure). |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_X509_CertOptions"></a>X509.CertOptions Enumeration

 Options to create X.509 certificate. 

#### Syntax

[`C#`]

```
[FlagsAttribute]
public enum CertOptions
```

[`VB.NET`]

```
<FlagsAttribute> _
Public Enumeration CertOptions
```

#### Members

|  | Member name | Description |
|  | Default | Default options |
|  | FormatPem | Create in PEM-encoded text file [default = binary DER-encoded] |
|  | UTF8String | Encode distinguished name as UTF8String [default = PrintableString] |
|  | NoBasicConstraints | Disable the BasicConstraints extension [default = include] |
|  | SetAsCA | Set the BasicConstraints subject type to be a CA [default = End Entity] |
|  | VersionOne | Create a Version 1 certificate, i.e. no extensions [default = Version 3] |
|  | AuthKeyId | Add the issuer's KeyIdentifier, if present, as an AuthorityKeyIdentifer [default = do not add] |
|  | Pss_SaltLenZero | Use a zero-length salt in an RSA-PSS signature [default = hLen the length of the digest output] |
|  | Ecdsa_Deterministic | Use the deterministic digital signature generation procedure of [RFC6979] for an ECDSA signature. |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_X509_CrlOptions"></a>X509.CrlOptions Enumeration

 Options to create Certificate Revocation List (CRL) 

#### Syntax

[`C#`]

```
[FlagsAttribute]
public enum CrlOptions
```

[`VB.NET`]

```
<FlagsAttribute> _
Public Enumeration CrlOptions
```

#### Members

|  | Member name | Description |
|  | Default | Default options |
|  | FormatPem | Create in PEM-encoded text file [default = binary DER-encoded] |
|  | Pss_SaltLenZero | Use a zero-length salt in an RSA-PSS signature [default = hLen the length of the digest output] |
|  | Ecdsa_Deterministic | Use the deterministic digital signature generation procedure of [RFC6979] for an ECDSA signature. |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_X509_CsrOptions"></a>X509.CsrOptions Enumeration

 Options to create PKCS#10 certificate signing request (CSR) 

#### Syntax

[`C#`]

```
[FlagsAttribute]
public enum CsrOptions
```

[`VB.NET`]

```
<FlagsAttribute> _
Public Enumeration CsrOptions
```

#### Members

|  | Member name | Description |
|  | Default | Default options |
|  | FormatBinary | Create in binary format [default = PEM-encoded text file] |
|  | UTF8String | Encode distinguished name as UTF8String [default = PrintableString] |
|  | RequestKludge | Create a request with the "kludge" that omits the strictly mandatory attributes completely [default = include attributes with zero-length field] |
|  | Pss_SaltLenZero | Use a zero-length salt in an RSA-PSS signature [default = hLen the length of the digest output] |
|  | Ecdsa_Deterministic | Use the deterministic digital signature generation procedure of [RFC6979] for an ECDSA signature. |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_X509_KeyUsageOptions"></a>X509.KeyUsageOptions Enumeration

 Options for key usage in certificate 

#### Syntax

[`C#`]

```
[FlagsAttribute]
public enum KeyUsageOptions
```

[`VB.NET`]

```
<FlagsAttribute> _
Public Enumeration KeyUsageOptions
```

#### Members

|  | Member name | Description |
|  | None | Key usage extension is not included. |
|  | DigitalSignature | subject public key is used for verifying digital signatures. |
|  | NonRepudiation | subject public key is used to verify digital signatures used to provide a non-repudiation service. |
|  | KeyEncipherment | subject public key is used for enciphering private or secret keys, i.e., for key transport. |
|  | DataEncipherment | subject public key is used for directly enciphering raw user data (uncommon). |
|  | KeyAgreement | subject public key is used for key agreement. |
|  | KeyCertSign | subject public key is used for verifying signatures on public key certificates. |
|  | CrlSign | subject public key is used for verifying signatures on certificate revocation lists. |
|  | EncipherOnly | subject public key may be used only for enciphering data while performing key agreement (only if keyAgreement bit is also set). |
|  | DecipherOnly | subject public key may be used only for deciphering data while performing key agreement (only if keyAgreement bit is also set). |

#### Remarks

Reference: [RFC5280] s4.2.1.3 Key Usage

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_X509_OutputOpts"></a>X509.OutputOpts Enumeration

 Options to format or re-encode output. 

#### Syntax

[`C#`]

```
[FlagsAttribute]
public enum OutputOpts
```

[`VB.NET`]

```
<FlagsAttribute> _
Public Enumeration OutputOpts
```

#### Members

|  | Member name | Description |
|  | Default | Default options |
|  | Latin1 | Encode distinguished name in Latin-1 encoding, if possible. |
|  | Unicode | Output distinguished name in Unicode character set (UTF-8 or UTF-16 as appropriate). |
|  | Ldap | Output distinguished name in LDAP string representation. |
|  | Decimal | Output serial number in decimal format [default = hex]. |

[[Contents](#topofpage)] [[Index](#index)]

---

### <a id="T_Xof_Alg"></a>Xof.Alg Enumeration

 eXtendable-Output Function (XOF) algorithm. 

#### Syntax

[`C#`]

```
public enum Alg
```

[`VB.NET`]

```
Public Enumeration Alg
```

#### Members

|  | Member name | Description |
|  | Shake128 | SHAKE128 (as per FIPS PUB 202) |
|  | Shake256 | SHAKE256 (as per FIPS PUB 202) |
|  | Mgf1_Sha1 | MGF1-SHA-1 (as per PKCS#1) |
|  | Mgf1_Sha256 | MGF1-SHA-256 (as per PKCS#1) |
|  | Mgf1_Sha512 | MGF1-SHA-512 (as per PKCS#1) |

[[Contents](#topofpage)] [[Index](#index)]

---

<a id="errorcodes"></a>Error Handling and Error Codes
-----------------------------------------------------

### Error Codes

```

0 = OK, success, no error (SUCCESS_NO_ERROR)
1 = Cannot open input file (OPEN_ERROR)
2 = Cannot create output file (CREATE_ERROR)
3 = File read error (READ_ERROR)
4 = File write error (WRITE_ERROR)
5 = Not enough memory (MEMORY_ERROR)
6 = Parameter is wrong or missing (BAD_PARAM_ERROR)
7 = Data in wrong format (BAD_FORMAT_ERROR)
8 = Invalid data (INVALID_DATA_ERROR)
9 = Unexpected end of file found (EOF_ERROR)
10 = Required data not found (MISSING_ERROR)
11 = Value out of range (OUT_OF_RANGE_ERROR)
12 = Duplicate data (DUP_ERROR)
13 = Misc file IO error (IO_ERROR)
14 = Unexpected NULL value (NULL_ERROR)
15 = Decryption error (DECRYPT_ERROR)
16 = Item has expired or is not yet valid (EXPIRED_ERROR)
17 = Invalid option (BAD_FLAG_ERROR)
18 = Failed to wipe data (WIPE_ERROR)
19 = Item is not supported (NOT_SUPPORTED_ERROR)
20 = No data found to process (NO_DATA_ERROR)
21 = No match found (NO_MATCH_ERROR)
22 = Signature is invalid (SIGNATURE_ERROR)
23 = Failed a test e.g. known answer test (TEST_FAILED_ERROR)
24 = Key generation failed (KEYGEN_FAILED_ERROR)
25 = Certificate issuer error (ISSUER_ERROR)
26 = Data not a valid length (BAD_LENGTH_ERROR)
27 = Invalid XML format (BAD_XML_ERROR)
29 = Not a valid query (BAD_QUERY_ERROR)
30 = Not enough room in output buffer (SHORT_BUF_ERROR)
31 = Zlib compression error (ZLIB_COMPR_ERROR)
33 = Invalid key length (BAD_KEY_LEN_ERROR)
34 = Invalid block length (BAD_BLK_LEN_ERROR)
35 = Invalid mode (BAD_MODE_ERROR)
36 = Invalid key (BAD_KEY_ERROR)
37 = Invalid initialization vector (BAD_IV_ERROR)
38 = Invalid IV length (BAD_IV_LEN_ERROR)
39 = Unable to encode (ENCODING_ERROR)
42 = Item has been revoked (REVOCATION_ERROR)
43 = Certificate path is invalid (CERT_PATH_ERROR)
201 = PRNG: Cannot open input file (PRNG_ERR_FILE_OPEN)
202 = PRNG: Cannot create output file (PRNG_ERR_FILE_CREATE)
203 = PRNG: File read error (PRNG_ERR_FILE_READ)
204 = PRNG: File write error (PRNG_ERR_FILE_WRITE)
205 = PRNG: File locking error (PRNG_ERR_FILE_LOCK)
210 = PRNG: Uninstantiation failed (PRNG_ERR_UNINST)
211 = PRNG: Requested length is too large (PRNG_ERR_TOOBIG)
212 = PRNG: Function failed (PRNG_ERR_FAILURE)
213 = PRNG: Invalid input parameter (PRNG_ERR_BADPARAM)
214 = PRNG: Function is not available (PRNG_ERR_NOTAVAIL)
299 = PRNG: Catastrophic failure (PRNG_ERR_CATASTROPHIC)
9745 = Something not expected to happen has happened (INTERNAL_ERROR)
9999 = Miscellaneous error (MISC_ERROR)

```

### Error Handling

If an error occurs the function will return one of the above nonzero error codes to indicate the general nature of the problem.
This may be a positive or negative value depending on the function.
Functions that normally return a positive value to indicate success will return an error code as a negative number.
Functions that return zero to indicate success will return a nonzero error code, either positive or negative, depending
on obscure historical reasons (to maintain backwards compatibility, sorry).

Use the [`PKI_ErrorLookup`](#PKI_ErrorLookup) function 
or the [General.ErrorLookup](#M_General_ErrorLookup) method 
to get the corresponding
error message for a given error code.

If you need to check for a specific error, please use the defined constants (`XXXX_ERROR`) instead of hard-coding the numerical values, 
which may change in future releases.

More than one error may occur during a call to a function. 
The code returned by a function will reflect the last error that occurred in the chain.
Use the [`PKI_ErrorCode`](#PKI_ErrorCode) function 
or [General.ErrorCode](#M_General_ErrorCode) method
to find the code of the first error that occurred.
More details on the error can usually be found by using the 
[`PKI_LastError`](#PKI_LastError)
function or  [General.LastError](#M_General_LastError) method 
which contains a description of the error or errors that have occurred. 
Be warned that not all errors set this description.

[[Contents](#topofpage)] [[Index](#index)]

<a id="acks"></a>Acknowledgements
---------------------------------

The source code used in
CryptoSys PKI Pro
is original code written by David Ireland except for the following:

* The DES algorithm includes code by Richard Outerbridge
placed in the public domain August 1992.
* The AES algorithm includes code placed in the public domain by Vincent Rijmen, Antoon Bosselaers and Paulo Barreto in December 2000.
* The SHA-1 algorithm includes code derived from 100% public domain code
by Steve Reid <steve@edmweb.com> with modifications based on
work by Peter Gutmann
as posted to sci.crypt in message <30ajo5$oe8@ccu2.auckland.ac.nz>.
* The code for SHA-3 and its family uses code derived from public domain code by Ronny Van Keer, May 2012, <http://keccak.noekeon.org/>.
* The code for RIPEMD-160 is adapted from software written by Antoon Bosselaers [[RMD](#RMD)].
* The HMAC algorithm includes code from RFC 2104 *HMAC: Keyed-Hashing for Message
Authentication* [[HMAC](#HMAC)].
* The code to read and write ASN.1 files uses techniques from the `DUMPASN1.C` program
by Peter Gutmann <http://www.cs.auckland.ac.nz/~pgut001/dumpasn1.c>.
* The ZLIB data compression utilities use source code with permission from the
*'zlib' general purpose compression library*
version 1.2.3 Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler.
* The code for curve25519 uses code under an MIT license by Mehdi Sotoodeh
<https://github.com/msotoodeh/curve25519>.
* The code for curve448 is based on code by Mike Hamburg under an MIT license
<https://git.zx2c4.com/goldilocks/>.
* The code for Salsa20 and ChaCha20 uses code derived from public domain code by D.J. Bernstein, <http://cr.yp.to/djb.html>.
* The code for Poly1305 uses code adapted from public domain software by Andrew Moon, <https://github.com/floodyberry/poly1305-donna>.
* Multiple-precision arithmetic is carried out using a modified version of the `BIGDIGITS` 
library first published June 2001 by David Ireland 
<[https://www.di-mgt.com.au/bigdigits.html](https://www.di-mgt.com.au/bigdigits.html "External link")>.
* The code to prompt for keyboard entropy and wipe files is derived from code published in 
*Secure Programming Cookbook* [[VIEG03](#VIEG03)].
* The code to process JSON uses source code 'json.c' Copyright (C) 2011 Joseph A. Adams (joeyadams3.14159@gmail.com).
* The code to call Intel DRNG functions uses source code Copyright (C) 2014, Intel Corporation with [conditions](https://cryptosys.net/docs/intel_drng_license.txt "External link").
* Some code to produce incidental pseudorandom numbers (*not* the core secure Random Number Generator) uses source code from "TinyMT32 Pseudo Random Number Generator (PRNG)" 
Copyright (c) 2011, 2013 Mutsuo Saito, Makoto Matsumoto, Hiroshima University and The University of Tokyo
under a BSD-3-Clause [license](https://github.com/MersenneTwister-Lab/TinyMT/blob/master/LICENSE.txt "External link").
* The MD5 algorithm includes code derived from the *RSA Data Security, Inc. MD5 Message-Digest Algorithm*
[[RFC1321](#RFC1321)]
which is covered by the following licence:

    > Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved.

    > License to copy and use this software is granted provided that it is identified as the 
        > ``RSA Data Security, Inc. MD5 Message-Digest Algorithm'' in all material mentioning or 
        > referencing this software or this function.

    > License is also granted to make and use derivative works provided that such works are 
        > identified as ``derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm'' 
        > in all material mentioning or referencing the derived work.

    > RSA Data Security, Inc. makes no representations concerning either the merchantability 
        > of this software or the suitability of this software for any particular purpose. 
        > It is provided ``as is'' without express or implied warranty of any kind.

    > These notices must be retained in any copies of any part of this documentation and/or software.

* Ditto for MD2, the "RSA Data Security, Inc. MD2 Message Digest Algorithm" [[RFC1319](#RFC1319)].

Thanks to the guys at [NullSoft](http://nsis.sourceforge.net/Main_Page "External link") for their
Nullsoft Scriptable Install System.

*[New in v20.5]*
We are most grateful to Daniel Gillmor for the latest *S/MIME Example Keys and Certificates* in RFC9216 [[SMIME-LAMPS](#SMIME-LAMPS)].

[[Contents](#topofpage)] [[Index](#index)]

<a id="References"></a>Primary References
-----------------------------------------

These are the primary references we used to create CryptoSys PKI Pro.

* <a id="CMS"></a>**[CMS]**
[RFC 5652](https://tools.ietf.org/html/rfc5652 "External link"),
 *Cryptographic Message Syntax (CMS)*,
R. Housley, September 2009 (obsoletes RFC3852, RFC3369, RFC2630).
* <a id="CMSALG"></a>**[CMSALG]**
[RFC 3370](https://tools.ietf.org/html/rfc3370 "External link"),
 *Cryptographic Message Syntax (CMS) Algorithms*, 
 R. Housley, August 2002.
* <a id="FIPS180"></a>**[FIPS180]**
Federal Information Processing Standard,
FIPS PUB 180-4 *Secure Hash Standard (SHS)*, 
U.S. Department of Commerce/National Institute of Standards and Technology, August 2015.
([NIST.FIPS.180-4](https://doi.org/10.6028/NIST.FIPS.180-4 "External link")).
* <a id="FIPS197"></a>**[FIPS197]**
Federal Information Processing Standard,
FIPS PUB 197 *Advanced Encryption Standard (AES)*,  
U.S. Department of Commerce/National Institute of Standards and Technology, 26 November 2001,
Updated May 9, 2023.
([NIST.FIPS.197](https://doi.org/10.6028/NIST.FIPS.197-upd1 "External link")).
* <a id="FIPS198"></a>**[FIPS198]**
Federal Information Processing Standard,
FIPS PUB 198-1 *The Keyed-Hash Message Authentication Code (HMAC)*,  
U.S. Department of Commerce/National Institute of Standards and Technology, July 2008.
([NIST.FIPS.198-1](https://doi.org/10.6028/NIST.FIPS.198-1 "External link")).
* <a id="FIPS202"></a>**[FIPS202]**
Federal Information Processing Standard,
FIPS PUB 202 *SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions*,  
U.S. Department of Commerce/National Institute of Standards and Technology, August 2015.
([NIST.FIPS.202](https://doi.org/10.6028/NIST.FIPS.202 "External link")).
* <a id="JWK"></a>**[JWK]**
[RFC 7517](https://tools.ietf.org/html/rfc7517 "External link"),
 *JSON Web Key (JWK)*, 
 M. Jones, May 2015.
* <a id="PKCS1"></a>**[PKCS1]**
PKCS #1,
*RSA Cryptography Standard*,
RSA Laboratories, Version 2.2, October 2012 (republished as [[RFC8017](#RFC8017)]).
* <a id="PKCS5"></a>**[PKCS5]**
PKCS #5,
*Password-Based Encryption Standard*,
RSA Laboratories, Version 2.2, October 2012 
(republished as [[RFC8018](#RFC8018)]).
* <a id="PKCS8"></a>**[PKCS8]**
PKCS #8,
*Private-Key Information Syntax Standard*,
RSA Laboratories, Version 1.2, Nov 1993  (republished as [[RFC5208](#RFC5208)] and [[RFC5958](#RFC5958)])
* <a id="PKCS10"></a>**[PKCS10]**
PKCS #10,
*Certification Request Syntax Standard*,
RSA Laboratories, Version 1.7, May 2000 (republished as [[RFC2986](#RFC2986) plus [[RFC5967](#RFC5967)]).
* <a id="PKCS12"></a>**[PKCS12]**
PKCS #12,
*Personal Information Exchange Syntax*,
RSA Laboratories, Version 1.1, October 2012 (republished as [[RFC7292](#RFC7292)]).
* <a id="PKCS-EX"></a>**[PKCS-EX]**
Burton S Kaliski, Jr, 
 *Some Examples of the PKCS Standards*, RSA Laboratories Technical Note, Nov 1993.
* <a id="PKIX"></a>**[PKIX]**
[RFC 5280](https://tools.ietf.org/html/rfc5280 "External link"),
 *Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile*, 
 R. Housley et al, May 2008
* <a id="PKIXALG"></a>**[PKIXALG]**
[RFC 3279](https://tools.ietf.org/html/rfc3279 "External link"),
 *Algorithms and Identifiers for the Internet X.509 Public Key Infrastructure
       Certificate and Certificate Revocation List (CRL) Profile*, 
 R. Housley et al, April 2002
* <a id="RFC3274"></a>**[RFC3274]**
[RFC 3274](https://tools.ietf.org/html/rfc3274 "External link"),
 *Compressed Data Content Type for
	Cryptographic Message Syntax (CMS)*, 
 P. Gutmann, June 2002.
* <a id="RFC3565"></a>**[RFC3565]**
[RFC 3565](https://tools.ietf.org/html/rfc3565 "External link"),
 *Use of the Advanced Encryption Standard (AES) Encryption
Algorithm in Cryptographic Message Syntax (CMS)*, 
 J. Schaad, July 2003.
* <a id="RFC4056"></a>**[RFC4056]**
[RFC 4056](https://tools.ietf.org/html/rfc4056 "External link"), 
*Use of the RSASSA-PSS Signature Algorithm in Cryptographic Message Syntax (CMS)*.
J. Schaad. June 2005.
* <a id="RFC5116"></a>**[RFC5116]**
[RFC 5116](https://tools.ietf.org/html/rfc5116 "External link"), 
*An Interface and Algorithms for Authenticated Encryption*.
D. McGrew. January 2008.
* []()**[RFC5639]**
[RFC 5639](https://tools.ietf.org/html/rfc5639 "External link")
*Elliptic Curve Cryptography (ECC) Brainpool Standard Curves and Curve Generation*.
M. Lochter, J. Merkle. March 2010.
* <a id="RFC6090"></a>**[RFC6090]**
[RFC 6090](https://tools.ietf.org/html/rfc6090 "External link"), *Fundamental Elliptic Curve Cryptography Algorithms*, McGrew, D., Igoe, K., M. Salter, February 2011
(and RFC Errata, [Erratum ID 3920](https://www.rfc-editor.org/errata_search.php?rfc=6090 "External link")).
* <a id="RFC6960"></a>**[RFC6960]**
[RFC 6960](https://tools.ietf.org/html/rfc6960 "External link"),
 *X.509 Internet Public Key Infrastructure
Online Certificate Status Protocol - OCSP*, 
 M. Myers, et al, June 2013.
* <a id="RFC6979"></a>**[RFC6979]**
[RFC 6979](https://tools.ietf.org/html/rfc6979 "External link")
*Deterministic Usage of the Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA)*.
T. Pornin. August 2013.
* <a id="RFC7748"></a>**[RFC7748]**
[RFC 7748](https://tools.ietf.org/html/rfc7748 "External link")
*Elliptic Curves for Security*.
A. Langley, M. Hamburg, S. Turner. January 2016.
* **<a id="RFC7914"></a>[RFC7914]**
[RFC 7914](https://tools.ietf.org/html/rfc7914 "External link") *The scrypt Password-Based Key Derivation Function*.
C. Percival, S. Josefsson. 2016.
* <a id="RFC8032"></a>**[RFC8032]**
[RFC 8032](https://tools.ietf.org/html/rfc8032 "External link")
*Edwards-Curve Digital Signature Algorithm (EdDSA)*.
S. Josefsson, I. Liusvaara. January 2017.
* <a id="RFC8103"></a>**[RFC8103]**
[RFC 8103](https://tools.ietf.org/html/rfc8103 "External link")
*Using ChaCha20-Poly1305 Authenticated Encryption in the Cryptographic Message Syntax (CMS)*.
R. Housley. February 2017.
* **<a id="RFC8439"></a>[RFC8439]**
[RFC 8439](https://tools.ietf.org/html/rfc8439 "External link") *ChaCha20 and Poly1305 for IETF Protocols*.
Y. Nir, A. Langley. June 2018. (Obsoletes RFC7539)
* <a id="SMIME-EX"></a>**[SMIME-EX]**
[RFC 4134](https://tools.ietf.org/html/rfc4134 "External link"),
 *Examples of S/MIME Messages*, 
 P. Hoffman (ed), July 2005.
* <a id="SMIME-LAMPS"></a>**[SMIME-LAMPS]**
[RFC 9216](https://tools.ietf.org/html/rfc9216 "External link")
*S/MIME Example Keys and Certificates*.
D.K. Gillmor, Ed., April 2022.
* <a id="SMIME-MSG"></a>**[SMIME-MSG]**
[RFC 5751](https://tools.ietf.org/html/rfc5751 "External link"),
 *Secure/Multipurpose Internet Mail Extensions (S/MIME) Version 3.2 Message Specification*, 
 B. Ramsdell, S. Turner, January 2010 (obsoletes RFC2633, RFC3851).
* <a id="SP80090A"></a>**[SP80090A]**
NIST Special Publication 800-90A,
*Recommendation for Random Number Generation Using Deterministic Random Bit Generators*,
Elaine Barker and John Kelsey,
National Institute of Standards and Technology, June 2015.
[NIST.SP.800-90Ar1](http://dx.doi.org/10.6028/NIST.SP.800-90Ar1 "External link").

[[Contents](#topofpage)] [[Index](#index)]

<a id="Bibliography"></a>Bibliography
-------------------------------------

Other works we referred to in creating CryptoSys PKI Pro.

* <a id="AES-WRAP"></a>**[AES-WRAP]**
*AES Key Wrap Specification*,
National Institute of Standards and Technology,
16 November 2001. Superseded by [[SP800-38F](#SP800-38F)].
* <a id="BALE05"></a>**[BALE05]**
Francesco Balena and Giuseppe Dimauro,
*Practical Guidelines and Best Practices for Microsoft Visual Basic and Visual C# Developers*,
Microsoft Press, 2005, ISBN 0735621721.
* <a id="BTC-B58"></a>**[BTC-B58]**
Bitcoin Wiki,
*Base58Check encoding*,
<https://en.bitcoin.it/wiki/Base58Check_encoding>,
(accessed January 2016).
* <a id="BROW99"></a>**[BROW99]**
Steve Brown,
*Visual Basic Developer's Guide to the Win32 API*,
Sybex, 1999.
* <a id="CADES"></a>**[CADES]**
ETSI TS 103 173:
Electronic Signatures and Infrastructures (ESI) *CAdES Baseline Profile*,
V2.1.1 (2012-03), March 2012, <https://www.etsi.org/deliver/etsi_ts/103100_103199/103173/02.01.01_60/ts_103173v020101p.pdf>.
* <a id="CHAN"></a>**[CHAN]**
Mahesh Chand,
*Tutorial: Creating C# Class Library (DLL) Using Visual Studio .NET*,
<https://www.c-sharpcorner.com/article/tutorial-creating-C-Sharp-class-library-dll-using-visual-studi/> (accessed July 2006).
* <a id="COHE99"></a>**[COHE99]**
Aaron Cohen and Mike Woodring,
*Win32 Multithreaded Programming*,
O'Rielly, 1999.
* <a id="CURVE25519"></a>**[CURVE25519]**
Daniel J. Bernstein. 
*A state-of-the-art Diffie-Hellman function*.
<[http://cr.yp.to/ecdh.html](http://cr.yp.to/ecdh.html "External link")>, accessed 13 September 2020.
* <a id="DEVIL"></a>**[DEVIL]**
Scott Berinato,
*The Devil's Infosec Dictionary*,
<http://www.csoonline.com/article/220527/the-devil-s-infosec-dictionary>, (accessed July 2010).
* <a id="DOWD06"></a>**[DOWD06]**
Mark Dowd, John McDonald and Justin Schuh,
*The Art of Software Security Assessment*,
Addison-Wesley, 2006.
* <a id="DUBU00"></a>**[DUBU00]**
Olivier Dubuisson,
*ASN.1
Communication between Heterogeneous Systems*,
<http://asn1.elibel.tm.fr/en/book/>
<http://www.oss.com/asn1/booksintro.html>,
June 2000.
* **<a id="DRBGVS"></a>[DRBGVS]**
Timothy A. Hall,
*The NIST SP 800-90A Deterministic Random Bit Generator Validation System (DRBGVS)*,
National Institute of Standards and Technology, Updated 29 October 2015,
[DRBGVS.pdf](https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/drbg/DRBGVS.pdf "External link")
* <a id="ED25519"></a>**[ED25519]**
Daniel J. Bernstein,
Niels Duif,
Tanja Lange,
Peter Schwabe,
Bo-Yin Yang.
*Ed25519: high-speed high-security signatures*.
<[http://ed25519.cr.yp.to/](http://ed25519.cr.yp.to/ "External link")>, version 2017.01.22.
* <a id="EDIFACT"></a>**[EDIFACT]**
UN/EDIFACT Finance Group D6 SWG-F,
*Recommended Practice For Message Flow And Security For Edifact Payments*,
Version 2v03, 1 October 2000, <www.bsk.no/text/d6_rec_practices.pdf>, (accessed January 2009).
* <a id="FERG03"></a>**[FERG03]**
Niels Ferguson and Bruce Schneier,
*Practical Cryptography*,
John Wiley, 2003.
* <a id="FERG10"></a>**[FERG10]**
Niels Ferguson, Bruce Schneier and Tadayoshi Kohno,
*Cryptography Engineering*,
John Wiley, 2010.
* <a id="FIPS140"></a>**[FIPS140]**
Federal Information Processing Standards Publication
FIPS PUB 140-2 *Security Requirements for Cryptographic Modules*,
U.S. Department Of Commerce/National Institute of Standards and Technology,
25 May 2001, Change Notice 1 (10 October 2001) and Change Notice 2 (3 December 2002).
* <a id="FIPS140IG"></a>**[FIPS140IG]**
*Implementation Guidance for
FIPS PUB 140-1 and the Cryptographic
Module Validation Program*,
U.S. Department Of Commerce/National Institute of Standards and Technology,
update 10 January 2002.
* <a id="FIPS140XC"></a>**[FIPS140XC]**
Federal Information Processing Standards Publication
FIPS PUB 140-2 *Annex C: Approved Random Number Generators
for FIPS PUB 140-2*,
U.S. Department Of Commerce/National Institute of Standards and Technology,
draft, 24 January 2007.
* <a id="FIPS186"></a>**[FIPS186]**
Federal Information Processing Standard,
FIPS PUB 186-4 *Digital Signature Standard (DSS)*,  
U.S. Department of Commerce/National Institute of Standards and Technology, July 2013.
* <a id="GOLDILOCKS"></a>**[GOLDILOCKS]**
Mike Hamburg. 
*Ed448-Goldilocks, a new elliptic curve*.
<[http://eprint.iacr.org/2015/625.pdf](http://eprint.iacr.org/2015/625.pdf "External link")>, 2015.
* <a id="GUTPFX"></a>**[GUTPFX]**
Peter Gutmann, 
 *PFX - How Not to Design a Crypto Protocol/Standard*, 
 <http://www.cs.auckland.ac.nz/~pgut001/pubs/pfx.html>, (last accessed January 2007).
* <a id="GUTX509"></a>**[GUTX509]**
Peter Gutmann, 
*X.509 Style Guide*, <http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt>, Oct 2000.
* <a id="HANS97"></a>**[HANS97]**
David R. Hanson,
*C Interfaces and Implementations*,
Addison-Wesley, 1997.
* <a id="HMAC"></a>**[HMAC]**
[RFC 2104](https://tools.ietf.org/html/rfc2104 "External link") *HMAC: Keyed-Hashing for Message
Authentication*, Krawczyk, Bellare and Canetti, February 1997.
* <a id="HOWA02"></a>**[HOWA02]**
Michael Howard and David LeBlanc,
*Writing Secure Code*,
Microsoft Press, 2002.
* <a id="IEEE1363"></a>**[IEEE1363]**
Institute for Electrical and Electronics Engineers (IEEE) Standard 1363-2000,
*Standard Specifications for Public Key Cryptography*,
January 2000.
* <a id="INTEL-DRNG"></a>**[INTEL-DRNG]**
Intel Corporation,
*Intel Digital Random Number Generator (DRNG) Software Implmentation Guide*, ID 658356,
Revision 2.1, October 17, 2018
([link](https://www.intel.com/content/www/us/en/developer/articles/guide/intel-digital-random-number-generator-drng-software-implementation-guide.html "External link") accessed December 2023).
* <a id="ISO18033-2"></a>**[ISO18033-2]**
ISO/IEC 18033-2:2006,
*Information technology - Security techniques - Encryption algorithms - Part 2: Asymmetric ciphers*,
Ed. Victor Shoup, 2006.
The final committee draft version *FCD 18033-2*, dated December 2004, is available at 
<http://www.shoup.net/iso/std6.pdf>.
* <a id="ISO8601"></a>**[ISO8601]**
ISO 8601:1988(E),
*Data elements and interchange formats - Information interchange - Representation of dates and times*,
1988
(actually we just cribbed this reference from W3C's
*Date and Time Formats*,
<http://www.w3.org/TR/NOTE-datetime>, Misha Wolf and Charles Wicksteed, Sept 1997).
* <a id="JWA"></a>**[JWA]**
[RFC 7518](https://tools.ietf.org/html/rfc7518 "External link"),
 *JSON Web Algorithms (JWA)*, 
 M. Jones, May 2015.
* <a id="JWS"></a>**[JWS]**
[RFC 7515](https://tools.ietf.org/html/rfc7515 "External link"),
 *JSON Web Signature (JWS)*, 
 M. Jones et al, May 2015.
* <a id="KALI-ASN"></a>**[KALI-ASN]**
Burton S Kaliski, Jr, 
 *A Layman's Guide to a Subset of ASN.1, BER and DER*, RSA Laboratories Technical Note, Nov 1993.
* <a id="KELS98"></a>**[KELS98]**
John Kelsey, Bruce Schneier, David Wagner, Chris Hall, 
*Cryptanalytic Attacks on Pseudorandom Number Generators*, March 1998, 
available from
<http://www.schneier.com/paper-prngs.html>.
* <a id="KUHN"></a>**[KUHN]**
Markus Kuhn,
*UTF-8 and Unicode FAQ for Unix/Linux*,
<http://www.cl.cam.ac.uk/~mgk25/unicode.html>,
(accessed August 2006).
* <a id="LARM99"></a>**[LARM99]**
Prof John Larmouth,
*ASN.1 Complete*,
<http://www.oss.com/asn1/larmouth.html>,
Open Systems Solutions, 1999.
* <a id="MENE97"></a>**[MENE97]**
 Menezes, van Oorschot and Vanstone,
*Handbook of Applied Cryptography*,
CRC Press LLC, 1997.
* <a id="NIST-MATH"></a>**[NIST-MATH]**
USG National Security Agency,
*Mathematical routines for the NIST prime elliptic curves*,
April 2010, <https://www.nsa.gov/ia/_files/nist-routines.pdf> (accessed October 2015).
* <a id="NISPOM"></a>**[NISPOM]**
DOD 5220.22-M,
*National Industry Security Program Operating Manual (NISPOM)*,
US Department of Defense, January 1995.
* <a id="SIEM99"></a>**[SIEM99]**
Siemens Financial Services,
*Electronic Signing of PAYMUL Messages*,
autack.doc, April 1999, <crg.tbg5-finance.org/migs/Autack.doc> (accessed January 2009).
* <a id="PETZ99"></a>**[PETZ99]**
Charles Petzold,
*Programming Windows*, 5th edition,
Microsoft Press, 1999.
* <a id="PKCS7"></a>**[PKCS7]**
PKCS #7,
*Cryptographic Message Syntax Standard*,
RSA Laboratories, Version 1.5, Nov 1993 (also [[RFC2315](#RFC2315)]).
* <a id="PKCS7-EXT"></a>**[PKCS7-EXT]**
RSA Laboratories Technical Note,
*Extensions and Revisions to PKCS #7*,
Burton S. Kaliski Jr. and Kevin W. Kingdon, May 1997.
* <a id="PKIX-MAP"></a>**[PKIX-MAP]**
Internet Draft, 
 *PKIX Roadmap*, 
 IETF-PKIX Working Group, 
 <http://tools.ietf.org/html/draft-ietf-pkix-roadmap-09>,
 July 2002.
* <a id="RICH99"></a>**[RICH99]**
Jeffrey Richter,
*Programming Applications for Microsoft Windows*, 4th edition,
Microsoft Press, 1999.
* <a id="RFC1319"></a>**[RFC1319]**
[RFC 1319](https://tools.ietf.org/html/rfc1319 "External link"), 
 *The MD2 Message-Digest Algorithm*, B. Kaliski, RSA Data Security, Inc., April 1992.
* <a id="RFC1321"></a>**[RFC1321]**
[RFC 1321](https://tools.ietf.org/html/rfc1321 "External link"), 
 *The MD5 Message-Digest Algorithm*, R. Rivest, RSA Data Security, Inc., April 1992.
* <a id="RFC1421"></a>**[RFC1421]**
[RFC 1421](https://tools.ietf.org/html/rfc1421 "External link"), 
 *Privacy Enhancement for Internet Electronic Mail*, 
 J. Linn, February 1993.
* <a id="RFC1423"></a>**[RFC1423]**
[RFC 1423](https://tools.ietf.org/html/rfc1423 "External link"), 
 *Privacy Enhancement for Internet Electronic Mail: Part III: Algorithms, Modes, and Identifiers*, 
 D. Balenson, February 1993.
* <a id="RFC1924"></a>**[RFC1924]**
[RFC 1924](https://tools.ietf.org/html/rfc1924 "External link"), 
 *A Compact Representation of IPv6 Addresses*, R. Elz, April 1 1996.
* <a id="RFC2202"></a>**[RFC2202]**
[RFC 2202](https://tools.ietf.org/html/rfc2202 "External link"), 
*Test Cases for HMAC-MD5 and HMAC-SHA-1*, 
P. Cheng and R. Glenn, September 1997.
* <a id="RFC2279"></a>**[RFC2279]**
[RFC 2279](https://tools.ietf.org/html/rfc2279 "External link"), 
 *UTF-8, a transformation format of ISO 10646*, 
 F. Yergeau, January 1998.
* <a id="RFC2315"></a>**[RFC2315]**
[RFC 2315](https://tools.ietf.org/html/rfc2315 "External link"), 
*PKCS #7: Cryptographic Message Syntax Version 1.5*, 
B. Kaliski,  March 1998.
* <a id="RFC2634"></a>**[RFC2634]**
[RFC 2634](https://tools.ietf.org/html/rfc2634 "External link")
*Enhanced Security Services for S/MIME*.
P. Hoffman. June 1999.
* <a id="RFC2986"></a>**[RFC2986]**
[RFC 2986](https://tools.ietf.org/html/rfc2986 "External link")
*PKCS #10: Certification Request Syntax Specification Version 1.7*.
M. Nystrom, B. Kaliski. November 2000.
* <a id="RFC2898"></a>**[RFC2898]**
[RFC 2898](https://tools.ietf.org/html/rfc2898 "External link"), 
*PKCS #5: Password-Based Cryptography Specification Version 2.0*, 
B. Kaliski,  September 2000.
* <a id="RFC3211"></a>**[RFC3211]**
[RFC 3211](https://tools.ietf.org/html/rfc3211 "External link"), 
*Password-based Encryption for CMS*, 
P. Gutmann, December 2001.
* <a id="RFC3217"></a>**[RFC3217]**
[RFC 3217](https://tools.ietf.org/html/rfc3217 "External link"), 
*Triple-DES and RC2 Key Wrapping*, 
R. Housley, December 2001.
* <a id="RFC3275"></a>**[RFC3275]**
[RFC 3275](https://tools.ietf.org/html/rfc3275 "External link"), 
*XML-Signature Syntax and Processing*, 
D. Eastlake et al, March 2002.
* <a id="RFC3279"></a>**[RFC3279]**
[RFC 3279](https://tools.ietf.org/html/rfc3279 "External link")
*Algorithms and Identifiers for the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile*.
L. Bassham, W. Polk, R. Housley. April 2002.
* <a id="RFC3394"></a>**[RFC3394]**
[RFC 3394](https://tools.ietf.org/html/rfc3394 "External link"), 
*Advanced Encryption Standard (AES) Key Wrap Algorithm*, 
J. Schaad and R. Housley, September 2002.
* <a id="RFC3447"></a>**[RFC3447]**
[RFC 3447](https://tools.ietf.org/html/rfc3447 "External link")
*Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1*.
J. Jonsson, B. Kaliski. February 2003.
* <a id="RFC3537"></a>**[RFC3537]**
[RFC 3537](https://tools.ietf.org/html/rfc3537 "External link"), 
*HMAC Key Wrap*, 
J. Schaad and R. Housley, May 2003.
* <a id="RFC3560"></a>**[RFC3560]**
[RFC 3560](https://tools.ietf.org/html/rfc3560 "External link"), 
*Use of the RSAES-OAEP Key Transport Algorithm in
the Cryptographic Message Syntax (CMS)*, 
R. Housley, July 2003.
* <a id="RFC4050"></a>**[RFC4050]**
[RFC 4050](https://tools.ietf.org/html/rfc4050 "External link"), 
*Using the Elliptic Curve Signature Algorithm (ECDSA)
for XML Digital Signatures*, 
S. Blake-Wilson et al, April 2005.
* <a id="RFC4055"></a>**[RFC4055]**
[RFC 4055](https://tools.ietf.org/html/rfc4055 "External link"), 
*Additional Algorithms and Identifiers for RSA Cryptography for use in the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile*.
J. Schaad, B. Kaliski, R. Housley. June 2005.
* <a id="RFC4086"></a>**[RFC4086]**
[RFC 4086](https://tools.ietf.org/html/rfc4086 "External link"), 
*Randomness Requirements for Security*, 
D. Eastlake et al, June 2005.
* <a id="RFC4122"></a>**[RFC4122]**
[RFC 4122](https://tools.ietf.org/html/rfc4122 "External link"), 
*A Universally Unique IDentifier (UUID) URN Namespace*, 
Leach, P. and Mealling, M. and Salz, R., July 2005.
* <a id="RFC4231"></a>**[RFC4231]**
[RFC 4231](https://tools.ietf.org/html/rfc4231 "External link"), 
*Identifiers and Test Vectors for HMAC-SHA-224, HMAC-SHA-256,
 HMAC-SHA-384, and HMAC-SHA-512*, 
M. Nystrom, December 2005.
* <a id="RFC4262"></a>**[RFC4262]**
[RFC 4262](https://tools.ietf.org/html/rfc4262 "External link")
*X.509 Certificate Extension for Secure/Multipurpose Internet Mail Extensions (S/MIME) Capabilities*.
S. Santesson. December 2005.
* <a id="RFC4514"></a>**[RFC4514]**
[RFC 4514](https://tools.ietf.org/html/rfc4514 "External link"), 
 *Lightweight Directory Access Protocol (LDAP):
String Representation of Distinguished Names*, 
 K. Zeilenga, Ed., OpenLDAP Foundation, June 2006.
* <a id="RFC4519"></a>**[RFC4519]**
[RFC 4519](https://tools.ietf.org/html/rfc4519 "External link"), 
 *Lightweight Directory Access Protocol (LDAP):
Schema for User Applications*, 
A. Sciberras, Ed., June 2006.
* <a id="RFC4648"></a>**[RFC4648]**
[RFC 4648](https://tools.ietf.org/html/rfc4648 "External link"), 
 *The Base16, Base32, and Base64 Data Encodings*, 
 S. Josefsson, October 2006.
* <a id="RFC4754"></a>**[RFC4754]**
[RFC 4754](https://tools.ietf.org/html/rfc4754 "External link")
*IKE and IKEv2 Authentication Using the Elliptic Curve Digital Signature Algorithm (ECDSA)*.
D. Fu, J. Solinas. January 2007.
* <a id="RFC5035"></a>**[RFC5035]**
[RFC 5035](https://tools.ietf.org/html/rfc5035 "External link")
*Enhanced Security Services (ESS) Update: Adding CertID Algorithm Agility*.
J. Schaad. August 2007.
* <a id="RFC5083"></a>**[RFC5083]**
[RFC 5083](https://tools.ietf.org/html/rfc5083 "External link")
*Cryptographic Message Syntax (CMS) Authenticated-Enveloped-Data Content Type*.
R. Housley. November 2007.
* <a id="RFC5084"></a>**[RFC5084]**
[RFC 5084](https://tools.ietf.org/html/rfc5084 "External link")
*Using AES-CCM and AES-GCM Authenticated Encryption in the Cryptographic Message Syntax (CMS)*.
R. Housley. November 2007.
* <a id="RFC5208"></a>**[RFC5208]**
[RFC 5208](https://tools.ietf.org/html/rfc5208 "External link")
*Public-Key Cryptography Standards (PKCS) #8: Private-Key Information Syntax Specification Version 1.2*.
B. Kaliski. May 2008 (Obsoleted by [[RFC5958](#RFC5958)]).
* <a id="RFC5280"></a>**[RFC5280]**
[RFC 5280](https://tools.ietf.org/html/rfc5280 "External link")
*Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile*.
D. Cooper, S. Santesson, S. Farrell, S. Boeyen, R. Housley, W. Polk. May 2008.
* <a id="RFC5349"></a>**[RFC5349]**
[RFC 5349](https://tools.ietf.org/html/rfc5349 "External link")
*Elliptic Curve Cryptography (ECC) Support for Public Key Cryptography for Initial Authentication in Kerberos (PKINIT)*.
L. Zhu, K. Jaganathan, K. Lauter. September 2008.
* <a id="RFC5480"></a>**[RFC5480]**
[RFC 5480](https://tools.ietf.org/html/rfc5480 "External link")
*Elliptic Curve Cryptography Subject Public Key Information*.
S. Turner, D. Brown, K. Yiu, R. Housley, T. Polk. March 2009.
* <a id="RFC5652"></a>**[RFC5652]**
[RFC 5652](https://tools.ietf.org/html/rfc5652 "External link")
*Cryptographic Message Syntax (CMS)*.
R. Housley. September 2009.
* <a id="RFC5750"></a>**[RFC5750]**
[RFC 5750](https://tools.ietf.org/html/rfc5750 "External link"),
 *Secure/Multipurpose Internet Mail Extensions (S/MIME) Version 3.2 Certificate Handling*, 
 B. Ramsdell, January 2010 (Obsoletes RFC3850).
* <a id="RFC5753"></a>**[RFC5753]**
[RFC 5753](https://tools.ietf.org/html/rfc5753 "External link")
*Use of Elliptic Curve Cryptography (ECC) Algorithms in Cryptographic Message Syntax (CMS)*.
S. Turner, D. Brown. January 2010.
* <a id="RFC5754"></a>**[RFC5754]**
[RFC 5754](https://tools.ietf.org/html/rfc5754 "External link"),
 *Using SHA2 Algorithms with Cryptographic Message Syntax*, 
 S. Turner, January 2010 (Updates RFC3370).
* <a id="RFC5756"></a>**[RFC5756]**
[RFC 5756](https://tools.ietf.org/html/rfc5756 "External link")
*Updates for RSAES-OAEP and RSASSA-PSS Algorithm Parameters*.
S. Turner, D. Brown, K. Yiu, R. Housley, T. Polk. January 2010.
* <a id="RFC5869"></a>**[RFC5869]**
[RFC 5869](https://tools.ietf.org/html/rfc5869 "External link")
*HMAC-based Extract-and-Expand Key Derivation Function (HKDF)*.
H. Krawczyk, P. Eronen. May 2010.
* <a id="RFC5911"></a>**[RFC5911]**
[RFC 5911](https://tools.ietf.org/html/rfc5911 "External link")
*New ASN.1 Modules for Cryptographic Message Syntax (CMS) and S/MIME*.
P. Hoffman, J. Schaad. June 2010.
* <a id="RFC5912"></a>**[RFC5912]**
[RFC 5912](https://tools.ietf.org/html/rfc5912 "External link")
*New ASN.1 Modules for the Public Key Infrastructure Using X.509 (PKIX)*.
P. Hoffman, J. Schaad. June 2010.
* <a id="RFC5915"></a>**[RFC5915]**
[RFC 5915](https://tools.ietf.org/html/rfc5915 "External link")
*Elliptic Curve Private Key Structure*.
S. Turner, D. Brown. June 2010.
* <a id="RFC5958"></a>**[RFC5958]**
[RFC 5958](https://tools.ietf.org/html/rfc5958 "External link")
*Asymmetric Key Packages*.
S. Turner. August 2010.
* <a id="RFC5967"></a>**[RFC5967]**
[RFC 5967](https://tools.ietf.org/html/rfc5967 "External link")
*The application/pkcs10 Media Type*.
S. Turner. August 2010.
* <a id="RFC5990"></a>**[RFC5990]**
[RFC 5990](https://datatracker.ietf.org/doc/html/rfc5990 "External link")
*Use of the RSA-KEM Key Transport Algorithm in the Cryptographic Message Syntax (CMS)*.
J. Randall, B. Kaliski, J. Brainard, S. Turner. September 2010.
* <a id="RFC5990bis"></a>**[RFC5990bis]**
[RFC 5990bis](https://datatracker.ietf.org/doc/draft-ietf-lamps-rfc5990bis/ "External link")
*Use of the RSA-KEM Algorithm in the Cryptographic Message Syntax (CMS)
                     draft-ietf-lamps-rfc5990bis-10*.
R. Housley, S. Turner. July 2024.
* <a id="RFC6025"></a>**[RFC6025]**
[RFC 6025](https://tools.ietf.org/html/rfc6025 "External link")
*ASN.1 Translation*.
C. Wallace, C. Gardiner. October 2010.
* <a id="RFC6211"></a>**[RFC6211]**
[RFC 6211](https://tools.ietf.org/html/rfc6211 "External link")
*Cryptographic Message Syntax (CMS) Algorithm Identifier Protection Attribute*.
J. Schaad. April 2011.
* <a id="RFC6268"></a>**[RFC6268]**
[RFC 6268](https://tools.ietf.org/html/rfc6268 "External link")
*Additional New ASN.1 Modules for the Cryptographic Message Syntax (CMS)
          and the Public Key Infrastructure Using X.509 (PKIX)*.
J. Schaad, S. Turner. July 2011.
* []()**[RFC7027]**
[RFC 7027](https://tools.ietf.org/html/rfc7027 "External link")
*Elliptic Curve Cryptography (ECC) Brainpool Curves for Transport Layer Security (TLS)*.
J. Merkle, M. Lochter. October 2013.
* <a id="RFC7292"></a>**[RFC7292]**
[RFC 7292](https://tools.ietf.org/html/rfc7292 "External link")
*PKCS #12: Personal Information Exchange Syntax v1.1*.
K. Moriarty, Ed., M. Nystrom, S. Parkinson, A. Rusch, M. Scott. July 2014.
* <a id="RFC7468"></a>**[RFC7468]**
[RFC 7468](https://tools.ietf.org/html/rfc7468 "External link")
*Textual Encodings of PKIX, PKCS, and CMS Structures*,
S. Josefsson, S. Leonard. April 2015.
* <a id="RFC7515"></a>**[RFC7515]**
[RFC 7515](https://tools.ietf.org/html/rfc7515 "External link")
*JSON Web Signature (JWS)*.
M. Jones, J. Bradley, N. Sakimura. May 2015.
* <a id="RFC8017"></a>**[RFC8017]**
[RFC 8017](https://tools.ietf.org/html/rfc8017 "External link")
*PKCS #1: RSA Cryptography Specifications Version 2.2*.
K. Moriarty, Ed., B. Kaliski, J. Jonsson, A. Rusch. November 2016.
* <a id="RFC8018"></a>**[RFC8018]**
[RFC 8018](https://tools.ietf.org/html/rfc8018 "External link")
*PKCS #5: Password-Based Cryptography Specification Version 2.1*.
K. Moriarty, Ed., B. Kaliski, A. Rusch. January 2017.
* <a id="RFC8410"></a>**[RFC8410]**
[RFC 8410](https://tools.ietf.org/html/rfc8410 "External link")
*Algorithm Identifiers for Ed25519, Ed448, X25519, and X448 for Use in the Internet X.509 Public Key Infrastructure*.
S. Josefsson, J. Schaad. August 2018.
* <a id="RFC8418"></a>**[RFC8418]**
[RFC 8418](https://tools.ietf.org/html/rfc8418 "External link")
*Use of the Elliptic Curve Diffie-Hellman Key Agreement Algorithm with X25519 and X448 in the Cryptographic Message Syntax (CMS)*.
R. Housley. August 2018.
* <a id="RFC8419"></a>**[RFC8419]**
[RFC 8419](https://tools.ietf.org/html/rfc8419 "External link")
*Use of Edwards-Curve Digital Signature Algorithm (EdDSA) Signatures in the Cryptographic Message Syntax (CMS)*.
R. Housley. August 2018.
* <a id="RFC8619"></a>**[RFC8619]**
[RFC 8619](https://datatracker.ietf.org/doc/html/rfc8619 "External link")
*Algorithm Identifiers for the HMAC-based Extract-and-Expand Key Derivation Function (HKDF)*.
R. Housley. June 2019.
* <a id="RFC8933"></a>**[RFC8933]**
[RFC 8933](https://tools.ietf.org/html/rfc8933 "External link")
*Update to the Cryptographic Message Syntax (CMS) for Algorithm Identifier Protection*.
R. Housley. October 2020.
* <a id="RFC9180"></a>**[RFC9180]**
[RFC 9180](https://tools.ietf.org/html/rfc9180 "External link")
*Hybrid Public Key Encryption*.
R. Barnes, et al. February 2022.
* <a id="RFC9629"></a>**[RFC9629]**
[RFC 9629](https://datatracker.ietf.org/doc/html/rfc9629 "External link")
*Using Key Encapsulation Mechanism (KEM) Algorithms in the Cryptographic Message Syntax (CMS)*.
R. Housley, J. Gray, T. Okubo. August 2024.
* <a id="RMD"></a>**[RMD]**
Antoon Bosselaers, *The RIPEMD-160 Page*,
<http://homes.esat.kuleuven.be/~bosselae/ripemd160.html>, last updated 25 August 2004.
* <a id="SAFECURVES"></a>**[SAFECURVES]**
Daniel J. Bernstein and Tanja Lange. 
*SafeCurves: choosing safe curves for elliptic-curve cryptography*.
[https://safecurves.cr.yp.to/](https://safecurves.cr.yp.to/ "External link"), version 2017.01.22.
* <a id="SCHN96"></a>**[SCHN96]**
Bruce Schneier,
*Applied Cryptography - Protocols, Algorithms and Source Code in C*,
2nd edition, John Wiley, 1996.
* <a id="SEAC05"></a>**[SEAC05]**
Robert C. Seacord,
*Secure Coding in C and C++*,
Addison-Wesley, 2005.
* <a id="SEC1"></a>**[SEC1]**
Certicom Research.
Standards for Efficient Cryptography, *SEC 1: Elliptic Curve Cryptography*,
version 2.0, May 2009, <http://www.secg.org/sec1-v2.pdf>.
* <a id="SIMO97"></a>**[SIMO97]**
Richard J Simon,
*Windows NT Win32 API SuperBible*,
Waite Group Press, 1997.
* <a id="SP800-20"></a>**[SP800-20]**
NIST Special Publication 800-20,
*Modes of Operation Validation System for the Triple Data
Encryption Algorithm (TMOVS): Requirements and Procedures*, 
National Institute of Standards and Technology, April 2000.
* <a id="SP800-38A"></a>**[SP800-38A]**
NIST Special Publication 800-38A,
*Recommendation for Block Cipher Modes of Operation*, 
National Institute of Standards and Technology, December 2001.
* <a id="SP800-38D"></a>**[SP800-38D]**
NIST Special Publication 800-38D,
*Recommendation for Block Cipher Modes of Operation:
Galois/Counter Mode (GCM) and GMAC*, 
National Institute of Standards and Technology, November 2007.
* <a id="SP800-38F"></a>**[SP800-38F]**
NIST Special Publication 800-38F,
*Recommendation for Block Cipher Modes of Operation:
Methods for Key Wrapping*, 
National Institute of Standards and Technology, December 2012.
* <a id="SP800-56A"></a>**[SP800-56A]**
NIST Special Publication 800-56A,
*Recommendation for Pair-Wise Key-Establishment Schemes Using Discrete Logarithm Cryptography*,
National Institute of Standards and Technology, Revision 3, April 2018.
* <a id="SP800-57"></a>**[SP800-57]**
NIST Special Publication 800-57,
*Recommendation for Key Management - Part 1: General*,
National Institute of Standards and Technology, Revision 5, May 2020.
* <a id="SP800-67"></a>**[SP800-67]**
NIST Special Publication 800-67,
*Recommendation for the Triple
Data Encryption Algorithm
(TDEA) Block Cipher*,
National Institute of Standards and Technology, Version 1.1, Revised May 2008.
* <a id="SP800-185"></a>**[SP800-185]**
NIST Special Publication 800-185,
*SHA-3 Derived Functions: cSHAKE, KMAC, TupleHash and ParallelHash*,
John Kelsey, Shu-jen Chang, Ray Perlner,
National Institute of Standards and Technology, December 2016.
[NIST.SP.800-185.pdf](https://doi.org/10.6028/NIST.SP.800-185 "External link").
* <a id="SPHINCS"></a>**[SPHINCS]**
*SPHINCS+ Submission to the NIST post-quantum project, v.3.1*.
Andreas Hülsing et al.
[sphincs+-r3.1-specification.pdf](https://sphincs.org/data/sphincs+-r3.1-specification.pdf "External link"), 
10 June 2022.
* <a id="STAL"></a>**[STAL]**
William Stallings,
*Cryptography and Network Security: Principles and Practice*,
4th edition, Prentice Hall, 2006.
* <a id="VIEG02"></a>**[VIEG02]**
John Viega and Gary McGraw,
*Building Secure Software*,
Addison-Wesley, 2002.
* <a id="VIEG03"></a>**[VIEG03]**
John Viega and Matt Messier,
*Secure Programming Cookbook for C and C++*,
O'Reilly, 2003.
* <a id="X-208"></a>**[X-208]**
International Telecommunication Union,
*Specification of Abstract Syntax Notation One (ASN.1)*,  
CCITT Recommendation X.208, 1988.
* <a id="X-209"></a>**[X-209]**
International Telecommunication Union,
*Specification of Basic Encoding Rules for Abstract Syntax Notation One (ASN.1)*,
CCITT Recommendation X.209, 1988.
* <a id="X-690"></a>**[X-690]**
International Telecommunication Union,
*ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER)*,
CCITT Recommendation X.690, July 2002.
* <a id="X9-23"></a>**[X9-23]**
ANSI X9.23-1998, American National Standard X9.23,
*Financial Institution Encryption of Wholesale Financial Messages*,
American National Standards Institute, 1998.
* <a id="X9-31"></a>**[X9-31]**
ANSI X9.31-1998, American National Standard X9.31,
*Digital Signatures using Reversible
Public Key Cryptography for the Financial Services Industry (rDSA)*,
Appendix A, American National Standards Institute, 1998.
* <a id="X9-44"></a>**[X9-44]**
ANSI X9.44-2007, American National Standard X9.44,
*Public Key Cryptography for the Financial Services Industry - Key Establishment Using Integer Factorization Cryptography*,
American National Standards Institute, 1998.
* <a id="X9-62"></a>**[X9-62]**
ANSI X9.62-1998, American National Standard X9.62,
*Public Key Cryptography For The Financial Services Industry:
	The Elliptic Curve Digital Signature Algorithm (ECDSA)*,
American National Standards Institute, 1998.
* <a id="X9-63"></a>**[X9-63]**
ANSI X9.63-2001, American National Standard X9.63,
*Public Key Cryptography For The Financial Services Industry:
	Key Agreement and Key Transport Using Elliptic Curve Cryptography*,
American National Standards Institute, November 2001.
* <a id="XKMS"></a>**[XKMS]**
W3C Recommendation, 
*XML Key Management Specification (XKMS 2.0)*, 
[https://www.w3.org/TR/xkms2/](https://www.w3.org/TR/xkms2/ "External link"), 28 June 2005.
* <a id="XMLDSIG"></a>**[XMLDSIG]**
W3C Recommendation, 
*XML-Signature Syntax and Processing*, 
[https://www.w3.org/TR/xmldsig-core/](https://www.w3.org/TR/xmldsig-core/ "External link"), 12 February 2002.
* <a id="XMLENC"></a>**[XMLENC]**
W3C Recommendation, 
*XML Encryption Syntax and Processing Version 1.1*, 
[https://www.w3.org/TR/xmlenc-core1/](https://www.w3.org/TR/xmlenc-core1/ "External link"), 11 April 2013.

[[Contents](#topofpage)] [[Index](#index)]

<a id="index"></a>Index
-----------------------

| ['Hello world' programs](#helloworld) [.NET Classes and Methods](#dotnetclassesandmethods) [.NET Help File](#dotnethelp) [A caution about insecure default algorithms](#cautionwithdefaults) [Acknowledgements](#acks) [Action if a self-test fails](#selftestfails) [Add an arbitrary X.509 Extension](#arbitraryx509extn) [Additional security attributes New in v12.4](#additionalsecurityattributes) [AOC policy for X.509 content](#aocpolicy) [ASN.1 analysis functions](#asn1functions) [ASN.1 objects: binary DER- and BER-encoded files vs PEM-encoded text files](#asn1objects) [Asn1 Class](#mx_Asn1) [AUTACK messages and ISO/IEC 9796-1 signatures](#autackmsgs) [Authenticated Encryption with Associated Data (AEAD)](#authencryptionaad) [Base64 alternative for X.509 certificates](#base64forcert) [Base64 and PEM string alternatives for CMS objects](#cmsbase64pem) [Base64url encoding and JSON Web Signatures (JWS)](#base64url) [Bibliography](#Bibliography) [Block Cipher Functions](#cipherfunctions) [C++ (STL) Functions](#cppfunctions) [C/C++ users must add one to this value...](#cusersaddone) [Can you read a key in compressed representation?](#compressedkey) [Cautions for C/C++ Users](#cautionsforcusers) [Certificate Revocation List (CRL) functions](#crlfunctions) [Changes in earlier versions](#changesearlier) [Cipher Class](#mx_Cipher) [CMS AuthEnvelopedData objects](#authenvelopeddata) [Cms Class](#mx_Cms) [CMS Content Types](#cmstypes) [CMS EnvelopedData objects](#envelopeddata) [CMS functions](#cmsfunctions) [CMS SignedData objects](#signeddata) [Cnv Class](#mx_Cnv) [Combining bitwise options](#bitwiseoptions) [Compiling with C](#compilingwithc) [Compr Class](#mx_Compr) [Compression functions](#comprfunctions) [Conditional Tests](#conditionaltests) [Continuous random number generator test:](#rngtest) [Conventions in this document](#Conventions) [Conversion functions](#cnvfunctions) [Converting strings to bytes and vice versa](#stringstobytes) [Converting VB6 to `VB.NET`](#vb6tovbnet) [Copyright Notice](#Copyright) [Core VBA/VB6 functions vs better wrapper functions](#corevbavswrappers) [Critical Errors](#criticalerrors) [Cross-reference between Functions and .NET Methods](#xrefdotnet) [Cryptographic algorithm test:](#cryptoalgtest) [Default encoding](#dndefaultencoding) [Detecting Win32 or X64 platform](#detectingplatform) [Ecc Class](#mx_Ecc) [Elliptic Curve Cryptography (ECC)](#eccrypto) [Elliptic curve cryptography functions](#eccfunctions) [Elliptic curve Diffie-Hellman (ECDH)](#ecdh) [Enumerations in .NET](#dotnetenumerations) [Error Handling and Error Codes](#errorcodes) [Examples of C code](#examplesccode) [eXtendable-output functions (XOF)](#xoffunctions) | [Filenames with 'International' characters](#filenamesinternational) [Find length of byte array](#findlengthbytearray) [General Class](#mx_General) [General functions](#genfunctions) [General Programming Issues](#generalprogramming) [Getting Started](#gettingstarted) [Hash Class](#mx_Hash) [HASH vs XOF vs MAC vs PRF vs KDF](#prfxof) [Hex format for NIST/SEC EC keys](#ecchexformat) [Hmac Class](#mx_Hmac) [HMAC Functions](#hmacfunctions) [Hpke Class](#mx_Hpke) [Hybrid Public Key Encryption (HPKE)](#hybridpke) [Hybrid Public Key Encryption (HPKE) functions](#hpkefunctions) [Index](#index) [Installation](#installation) [Intel(R) DRNG support](#inteldrng) [Internal key strings](#internalkeys) [Introduction to CryptoSys PKI Pro](#Introduction) [ISO 8601 date-time formats](#iso8601datetime) [ISO/IEC 9796-1 Formatting](#iso9796format) [Kdf Class](#mx_Kdf) [Key Derivation Functions](#kdffunctions) [Key Security](#keysecurity) [Key Storage Format (ECC)](#Keystorage-ecc) [Key Storage Format (RSA)](#Keystorage) [LDAP String Representation of Distinguished Names](#ldapstring) [List of .Net Methods](#methodlist) [List of Functions](#functionlist) [Message Digest Hash Functions](#hashfunctions) [New in this version](#newinthis) [Notes on VBA wrapper functions](#notesonvbawrapperfunctions) [Ocsp Class](#mx_Ocsp) [OCSP Functions](#ocspfunctions) [Optional Registry Settings](#registrysettings) [Other Issues For VB6/VBA Users](#otherissuesvb6) [Padding functions](#padfunctions) [Padding schemes for block ciphers](#paddingschemes) [Pair-wise consistency test:](#pairwiseconsistencytest) [Parameters for RSA-PSS and RSA-OAEP available in this Toolkit](#parametersrsapssoaep) [Passing a reference to an empty byte array in VB6/VBA](#passemptybytearray) [Password prompt functions](#promptfunctions) [Password-based encryption functions](#pbefunctions) [Pbe Class](#mx_Pbe) [Pem Class](#mx_Pem) [PEM string alternative for X.509 certificates, RSA and EC keys, etc](#pemstring) [PEM/binary file conversion functions](#pemfunctions) [Pfx Class](#mx_Pfx) [PFX Functions](#pfxfunctions) [Power-up Self-Tests](#powerupselftests) [Pre-dimensioning for VB6](#predimensioning) [Prf Class](#mx_Prf) [Primary References](#References) [Pseudorandom functions (PRF)](#prffunctions) [Pwd Class](#mx_Pwd) [Random Number Generator](#rnginfo) [Random number generator functions](#rngfunctions) [Raw RSA functions](#rawrsafunctions) | [Raw RSA Techniques](#rawrsa) [Return Values](#ReturnValues) [Revision History](#Revisions) [Rng Class](#mx_Rng) [RNG health test:](#rnghealthtest) [RNG Mechanisms](#rngmechanisms) [Rsa Class](#mx_Rsa) [RSA key functions](#rsafunctions) [RSA signature and encryption schemes: RSA-PSS and RSA-OAEP](#rsaschemes) [RSA2 Signing](#rsa2sign) [S/MIME functions](#smimefunctions) [Safe curves for elliptic cryptography](#eccsafecurves) [Security Issues](#securityissues) [Security options for encrypted private keys](#encryptedkeyoptions) [Self-Tests](#selftests) [Sig Class](#mx_Sig) [SIG functions](#sigfunctions) [Smime Class](#mx_Smime) [Software integrity test:](#softwareintegritytest) [Specifying an arbitrary RDN in a distinguished name](#arbitraryrdn) [Specifying Distinguished Names](#distnames) [Specifying the algorithm, mode and padding for generic block cipher functions](#cipheralgmode) [Specifying the signature algorithm in a SIG_ function](#sigalgorithm) [Summary of .NET Classes](#dotnetsummary) [Supported Algorithms](#SupportedAlgorithms) [Tdea Class](#mx_Tdea) [Technical Details](#technicaldetails) [Techniques to add known security strength to the RNG process](#rngtechniques) [Theory](#Theory) [Triple DES (TDEA/3DES) Functions](#tdeafunctions) [Type Conversions](#typeconversions) [Unsupported algorithms](#unsupportedalgorithms) [User-supplied entropy (seeds)](#rngentropy) [Using in MIME-conformant email messages](#usinginmime) [Using output in XML documents](#xmldocs) [Using with .NET: C# and `VB.NET`](#UsingWithDotNet) [Using with ANSI C](#UsingWithC) [Using With Borland C++](#borlandc) [Using with C++ (STL)](#UsingWithCpp) [Using with Classic Visual Basic VB6 and VBA](#UsingWithVB) [Using With MinGW gcc](#mingw) [Using with Python](#UsingWithPython) [UTF-8 and Latin-1](#utf8andlatin1) [UTF-8 encoding in distinguished names](#utf8forDN) [Valid key and block sizes for block cipher algorithms](#blockciphersizes) [VB6/C Function Summary](#vb6funcsummary) [VBA Wrapper Function List](#vbawrapperfunctionlist) [VBA Wrapper Functions](#vbawrapperfunctions) [Visual Basic or Visual Basic: VB6 vs `VB.NET`](#vb6vsvbdotnet) [Win64 (X64) Platform](#win64platform) [Wipe Class](#mx_Wipe) [Wipe functions](#wipefunctions) [X.509 certificate functions](#x509functions) [X.509 Extensions Parameter](#x509extensions) [X509 Class](#mx_X509) [Xof Class](#mx_Xof) [Zero-length byte arrays in VB6/VBA](#zerolengthbytearrays) |
| --- | --- | --- |

[[Contents](#topofpage)] [[Index](#index)]

<a id="Revisions"></a>Revision History
--------------------------------------

September 2025: Minor updates for markdown version. Updated links.
24 September 2024: Updated for Version 23.0. Added support for RSA-KEM with the Cryptographic Message Syntax (CMS). 
Added new features and improvements for CMS enveloped-data and signed-data creation.  

1 January 2024: Updated for Version 22.1. Upgraded random number generator (RNG) functions. Added support for Intel(R) DRNG, if available.  

23 October 2023: Updated for Version 22.0. Added support for elliptic curves Ed448 and X448, ChaCha20Poly1305 authenticated encryption, the SCRYPT password-based key derivation function,
and Hybrid Public Key Encryption (HPKE) as per RFC9180.  

1 January 2023: Updated for Version 21.0. Added support for SHA-3 and related functions.  

10 September 2022: Updated for Version 20.6. Added support for CMS Authenticated-Enveloped-Data objects, and kekri and pwri recipientInfo types.  

18 July 2022: Updated for Version 20.5. Added support for ECDH key agreement in enveloped-data objects and associated key derivation functions (KDF);
and support for AES256-SHA256 encryption in PKCS#12 (PFX) files.  

24 April 2022: Updated for Version 20.4. Added support for ECC Brainpool curves.  

1 January 2022: Updated for Version 20.3. Added interface to C++ (STL).  

3 October 2021: Updated for Version 20.2. Consolidated VBA modules for 32/64-bits and VBA wrapper functions. 
Rationalised .NET methods using .NET 4.0 optional parameters instead of .NET 2.0 overloads  

13 March 2021: Updated for Version 20.1.  

25 January 2021: Updated with documentation for VBA wrapper functions.  

17 October 2020: Updated for Version 20.0.  

12 May 2020: Updated for Version 12.4. Added additional security attributes for signed-data CMS objects.  

6 March 2020: Updated for Version 12.3. Added support to generate GUID strings; added advanced options when creating X.509 certificates and PKCS#10 certificate requests;
and support for stronger encryption for certificates in PKCS#12 (PFX) files.  

12 July 2019: Updated for Version 12.2.30. A minor upgrade to fix issues with multithreading and running on XP.  
 
20 May 2019: Updated for Version 12.2.20. A minor upgrade to fix multithreading issues.  
 
24 March 2019: Updated for Version 12.2.  Improved support for CMS (PKCS#7) signed-data and enveloped-data objects, and RSA keys represented in JSON Web Key (JWK) format.  

17 November 2018: Updated for Version 12.1. Added support for AES-GCM.  

19 June 2018: Updated for Version 12.0. Added support for RSA-PSS and RSA-OAEP; and support for ECDSA in X.509 certificates; and ZLIB compression.  

28 April 2018: Updated for Version 11.3. Beta release for v12.  

8 August 2017: Updated for Version 11.2. Various minor fixes and new convenience functions.  

20 May 2016: Updated for Version 11.1. Added new block cipher functions.  

8 March 2016: Updated for Version 11.0. Added elliptic curve cryptography.  

27 March 2015: Updated for Version 10.0. Major update to CryptoSys PKI Pro.  

2 September 2014: Updated for Version 3.10. Added block cipher functions with padding and password-based encryption (PBE) functions.  

8 September 2012: Updated for Version 3.9  

14 January 2012: Updated for Version 3.8  

1 July 2011: Updated for Version 3.7  

25 August 2010: Updated for Version 3.6  

2 May 2010: Updated for Version 3.5  

19 December 2009: Updated for Version 3.4.  

19 February 2009: Updated for Version 3.3.  

2 February 2008: Updated for Version 3.2. Added new block cipher functions and RSA-KEM (since withdrawn).  

2 August 2007: Updated for Version 3.1.  

27 March 2007: Updated for Version 3.0. Changes to RNG and internal key string storage. Added HMAC functions.  

12 August 2006: Updated for Version 2.9. Major re-write of manual.  

26 April 2006: Updated for Version 2.8. Added section on signed-data objects.  

11 December 2005: Updated for Version 2.7. Added `VB.NET` and C# syntax prototypes, and index.  

20 August 2005: Updated for Version 2.6. Added extra RSA functions for XML and message encoding, and support for PEM key files. 
Added section on Raw RSA Techniques. Added C/C++ syntax prototypes.  

9 May 2005: Updated for Version 2.5. Added extra HASH and TDEA functions; rephrased action if self-test fails.  

5 April 2005: Updated for Version 2.4. Added PFX functions and PEM export options.  

1 March 2005: Updated for Version 2.3.  

1 January 2005: Updated for Version 2.2. Added Boolean type description; added [in],[out] to parameters; other minor corrections.  

29 November 2004: Minor corrections to manual.  

24 November 2004: Updated for Version 2.1  

September 2004: Minor amendments to manual.  

25 February 2004: Version 2.0 manual first published by DI Management Services Pty Limited.  

December 2002: Proposed PKI functions first posted on <https://cryptosys.net/pki.html>.  

---

Copyright © 2004-25 D.I. Management Services Pty Ltd t/a CryptoSys ABN 78 083 210 584,
Australia.
All rights reserved.  

<[https://di-mgt.com.au](https://di-mgt.com.au "External link")>
<[https://cryptosys.net](https://cryptosys.net "External link")>

---

