CryptoSys PKI Pro Manual

Function List    X-refs    Method List    Error Codes    References    Index

Contents

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] 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] 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], and Cryptographic Message Syntax (CMS) [CMS] together with the relevant PKCS documents as our primary reference documents. CMS is a stricter subset of PKCS#7 [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. 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] and [XML-ENC] specifications to insert into XML documents, 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.

Getting Started

To get started, read the section on Installation and the section on your programming language:

and if you are a Visual Basic user, please read Visual Basic or Visual Basic: VB6 vs VB.NET.

Then try one of the 'Hello world' programs to make sure it works.

For more details, please read General Programming Issues 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 on our web site.

[Contents] [Index]

New in this version

Changes in Version 23.0 (September 2024):

[Contents] [Index]

Changes in earlier versions

Changes in Version 22.1 (1 January 2024):

Changes in Version 22.0 (23 October 2023):

Changes in Version 21.0.11 (11 June 2023):

Changes in Version 21.0 (1 January 2023):

Changes in Version 20.6 (10 September 2022):

Changes in Version 20.5 (18 July 2022):

Changes in Version 20.4 (24 April 2022):

Changes in Version 20.3 (8 January 2022):

Changes in Version 20.2 (3 October 2021):

Changes in Version 20.1 (13 March 2021):

Changes in Version 20.0 (17 October 2020):

Changes in Version 12.4 (12 May 2020):

Changes in Version 12.3 (6 March 2020):

Changes in Version 12.2 (24 March 2019):

Changes in Version 12.1 (17 November 2018):

Changes in Version 12.0 (20 June 2018):

Changes in Version 11.2 (8 August 2017):

Changes in Version 11.1 (20 May 2016):

Changes in Version 11.0 (8 March 2016):

Changes in Version 10.0 (27 March 2015):

Changes in Version 3.10 (2 September 2014):

Changes in Versions 3.9.1 to 3.9.4 (4 October 2012 to 9 October 2013):

Changes in Version 3.9 (8 September 2012):

Changes in Version 3.8 (14 January 2012):

Changes in Version 3.7 (1 July 2011):

Changes in Version 3.6 (25 August 2010):

Changes in version 3.5 (2 May 2010):

Changes in version 3.4 (19 December 2009):

Changes in version 3.3 (19 February 2009):

Changes in version 3.2 (2 February 2008):

Changes in version 3.1 (2 August 2007):

Changes in version 3.0 (27 March 2007):

Changes in version 2.9 (12 August 2006):

Changes in version 2.8 (26 April 2006):

Changes in version 2.7 (11 December 2005):

[Contents] [Index]

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] [Index]

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/>.

[Contents] [Index]

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]. For a more detailed work, see Some Examples of the PKCS Standards by RSA Laboratories [PKCS-EX], an old but still useful guide. If all else fails, try reading the primary 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] [Index]

Supported Algorithms

Please note A caution about insecure default algorithms.

Public key encryption and signature algorithms

Elliptic curve cryptography

Symmetric block cipher algorithms for content encryption

In addition, the following algorithm can be read by the CMS_ReadEnvData[ToString] functions:

Block cipher algorithms for key wrapping

Message digest hash algorithms

We keep MD2 here so we can reproduce the examples from RSA Laboratories' 1993 paper [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.

Password-based encryption algorithms

These algorithms from PKCS#5 and PKCS#12 can be used to create PKCS#8 encrypted private key files:

In addition to those above, the following legacy algorithms can be read by the RSA_ReadEncPrivateKey function:

RSA Key Formats

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.

Also supported are RSA private and public keys represented in XML format to XKMS 2.0 [XKMS] and JSON Web Key (JWK) format [JWK]. For more details, see Key Storage Format.

Elliptic Curve Key Formats

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.

Supported CMS Content Types

Only CMS objects with an id-data inner content type are supported.

X.509 Certificates

Unsupported algorithms

These algorithms from [PKIXALG] are not currently supported:

Key Storage Format (RSA)

Key Storage Format (ECC)

[Contents] [Index]

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:

AlgorithmDefaultMinimum recommendedOption to use
Message digestSHA-1SHA-256PKI_HASH_SHA256
HMACHMAC-SHA-1HMAC-SHA-256PKI_HMAC_SHA256
RSA signaturesha1WithRSAEncryptionsha256WithRSAEncryptionPKI_SIG_RSA_SHA256
RSA encryption schemeRSAES-PKCS1-v1_5RSAES-OAEPPKI_EME_OAEP
Password-based encryptionpbeWithSHAAnd3-KeyTripleDES-CBC"pkcs5PBES2" using pkcs5PBKDF2 with "aes128-CBC"PKI_PBE_PBKDF2_AES128
Symmetric encryptiondes-EDE3-CBCaes128-CBC/AES-128-GCM*PKI_BC_AES128/PKI_AEAD_AES_128_GCM

* Use the CIPHER_EncryptAEAD function or Cipher.EncryptAEAD Method 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.

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.

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 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.

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] [Index]

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.

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.

[Contents] [Index]

General Programming Issues

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 interface behave differently (and more conveniently) - please refer to the detailed documentation 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] [Index]

"Hello world" programs

The equivalent of the "Hello world" program for CryptoSys PKI Pro is to call the 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] [Index]

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] [Index]

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 and Cross-reference between Functions and .NET Methods.

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:

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:

[Contents] [Index]

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.

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.

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.

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))

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

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

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.

Other Issues For VB6/VBA Users

Notes on VBA wrapper functions

Use the VBA wrapper functions to avoid the pre-dimensioning issues for functions that output to a string or byte array. See VBA Wrapper Function List.

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 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] [Index]

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 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.

Type Conversions

The following type conversions apply between VB6/VBA and C/C++:-

VB6/VBAC/C++
ByVal x As Stringchar *x
ByRef x As Byteunsigned char *x
ByVal x As Longlong 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.

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.

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

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

Cautions for C/C++ Users

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.

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

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.

[Contents] [Index]

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.

Note: All the C++ methods are static and are called directly without creating any object.

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.

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.

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] [Index]

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 and Python CryptoSys PKI Cross Reference. To install the interface from PyPi
pip install cryptosyspki

[Contents] [Index]

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].

DeprecatedReplaced by
CNV_UTF8FromLatin1CNV_UTF8BytesFromLatin1
CNV_Latin1FromUTF8CNV_Latin1FromUTF8Bytes
CNV_CheckUTF8CNV_CheckUTF8Bytes
Cnv.CheckUTF8(String) (withdrawn)Cnv.CheckUTF8(Byte[]) 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 and equivalent method 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

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] [Index]

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 to get a ASCII filename that will work with any function in this Toolkit. Examples:

System FilenameShortPathName
你好.txtFC0F~1.TXT
こんにちは世界.txtC001~1.TXT
Приветмир.txtE173~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] [Index]

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).
  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 may be made and, if they exist, will be read and acted on by the module if a critical error 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).
  10. To check you have a valid version of the CryptoSys PKI Pro executable, please check the integrity checksums published on our web site.
  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 below.

Temporary file exception: [New in v12.0] The function ASN1_TextDumpToString and method Asn1.TextDumpToString create a locked temporary file which is automatically deleted.

[Contents] [Index]

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:

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 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] [Index]

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.

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] [Index]

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 and SIG_SignFile and the Sig class methods). [New in v20.0] You can also perform elliptic curve Diffie-Hellman key exchange (ECDH) - see 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 which is stored in encrypted form valid only for the current session. We support the following curves over prime fields:

Creating a new ECC key pair

To create a new elliptic curve key pair, use the 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]. 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] encrypted with a password. This is the (only) output when using ECC_MakeKeys and ECC_SaveEncKey. In a PEM-encoded file, this should begin with -----BEGIN ENCRYPTED PRIVATE KEY.
  2. ECPrivateKey [RFC5915]. This is the default output for a private key using ECC_SaveKey. In a PEM-encoded file, this should begin with -----BEGIN EC PRIVATE KEY.
  3. Unencrypted PKCS#8 PrivateKeyInfo [RFC5208] (more recently renamed as OneAsymmetricKey [RFC5958] but identical in structure in this case). This is an optional output for a private key using 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 function to read in a key in a hex format string, then you can save it as a file in a supported key format. If your key is in base58 encoding, use CNV_Base58ToBytes to decode, then 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 or ECC_ReadPublicKey, then save it as a file again using ECC_SaveKey or ECC_SaveEncKey. To obtain the public key from a private key, read the private key into an internal string and then use ECC_PublicKeyFromPrivate. To analyze an EC key file, read it into an internal string and use ECC_QueryKey.

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], 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]:
04||HEX(x)||HEX(y)
Compressed representation (beginning "02" or "03") is not supported due to patent issues.

Note that the format is different for the safe curves 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] 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] and is described in section E3.1 of [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" 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 and ECC_ReadPublicKey.

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] [Index]

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] and "curve448" (also known as "goldilocks") [GOLDILOCKS]. The use of X25519 and X448 for Elliptic Curve Diffie-Hellman key exchange (ECDH) is described in [RFC7748].

Ed25519 and Ed448 are elliptic curve signature schemes Edwards-curve Digital Signature Algorithm (EdDSA) described in [RFC8032]. Ed25519 uses the twisted Edwards curve "edwards25519", which is birationally equivalent to curve25519 [ED25519].

curve25519, edwards25519 and curve448 are "safe curves" [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] (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

Features of X448 and Ed448

Masking/clamping for X25519 and X448 private keys

Some differences from the NIST/SEC curves

[Contents] [Index]

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.

[Contents] [Index]

Self-Tests

The module performs power-up self-tests and conditional self-tests to ensure that it is functioning properly. Power-up self-tests are performed when the module is powered up, i.e. when the DLL is first attached to the parent Windows process. Conditional self-tests are performed when certain security functions are invoked.

Power-up Self-Tests

The following power-up self-tests are performed:-

Cryptographic algorithm test:

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]).

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.

Conditional Tests

The following conditional tests are performed:-

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.

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.

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. It is not possible to prevent the DLL from exiting if a critical error happens.

The user may call the power-up self-tests on demand with the 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] [Index]

Critical Errors

A Critical Error occurs if and only if one of the following events occur:

You should never see a critical error in practice unless the software module has been tampered with.

[Contents] [Index]

Optional Registry Settings

The following optional registry settings may be made to change the behaviour of the module if a critical error 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 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 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] [Index]

Random Number Generator

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]. Entropy is accumulated in "Fortuna" pools as described in Ferguson and Schneier, Practical Cryptography, [FERG03]. The full technical details are published on our web site.

The underlying RNG functions use the algorithms recommended in NIST SP 800-90A [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]). 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, 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.

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].

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 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.

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 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 from time to time in your application to save any existing entropy, and use 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 function when generating random data to force the user to generate entropy using random keystrokes and mouse movements. 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 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.

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.

[Contents] [Index]

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.

<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 below).

typedescriptionOID
CNcommonName2.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 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.)

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, specify the PKI_X509_UTF8 flag.

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 stringDefault encodingWith PKI_X509_UTF8
OU=abcPrintableString "abc"UTF8String "abc"
OU=#x616263PrintableString "abc"UTF8String "abc"
OU='a\62c'PrintableString "abc"UTF8String "abc"
C=M\e9xicoT61String "México"UTF8String "México"
C=#x4de97869636fT61String "México"UTF8String "México"
C=#x4dc3a97869636fT61String (garbage!)UTF8String "México"
CN=#xE5A4A7E58DABT61String (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.

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 "#" 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] LDAP Schema for User Applications.

Full DER-encoded Value using "#"

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

SyntaxExampleRemarks
<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).

[Contents] [Index]

LDAP String Representation of Distinguished Names

Use the PKI_X509_LDAP option with functions X509_CertIssuerName, X509_CertSubjectName and X509_QueryCert (with queries "issuerName" and "subjectName") to obtain the LDAP string representation of the distinguished name as per [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], namely

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. You must use the form described in Distinguished Names. The LDAP form is just for display.

[Contents] [Index]

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_MakeCertSelf and 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):

Extensions for making X.509 certificates only (duplicates ignored):

Extensions for making X.509 certificates and certificate requests:

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]!
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, 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, 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]. For examples of DER encodings see section 6 of [RFC5753] and section 8 of [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] 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]: "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] 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 below.

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] [Index]

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.

(And we used "AOC" many years before the election of any politician with the same moniker.)

[Contents] [Index]

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] [Index]

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]). PEM encoding is the base64 encoding [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.

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]
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 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] [Index]

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 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 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] [Index]

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.

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] [Index]

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 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] [Index]

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:

ValueAlgorithmOption
tdeaTriple DES, a.k.a. 3DES, des-ede3PKI_BC_TDEA
3desAlternative for Triple DESPKI_BC_3DES
desede3Another alternative for Triple DES (desede is OK)PKI_BC_DESEDE3
aes128AES-128PKI_BC_AES128
aes192AES-192PKI_BC_AES192
aes256AES-256PKI_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:

ValueModeOption
ecbElectronic Code Book mode (default)PKI_MODE_ECB
cbcCipher Block Chaining modePKI_MODE_CBC
ofbOutput Feedback mode PKI_MODE_OFB
cfb64/128-bit† Cipher Feedback mode PKI_MODE_CFB
ctrCounter mode PKI_MODE_CTR
gcmGalois/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:

strAlgAndModeDescriptionAlternative Option value
tdea-cbcTriple DES in CBC modePKI_BC_TDEA+PKI_MODE_CBC
3des-cbcditto PKI_BC_3DES+PKI_MODE_CBC
des-ede3-cbcditto PKI_BC_DESEDE3+PKI_MODE_CBC
tdea-ecbTriple DES in ECB modePKI_BC_TDEA+PKI_MODE_ECB
tdeaditto (ECB is default mode)PKI_BC_TDEA
aes128-cbcAES-128 in CBC modePKI_BC_AES128+PKI_MODE_CBC
aes256-ctrAES-256 in Counter modePKI_BC_AES256+PKI_MODE_CTR
aes192-gcmAES-192 in Galois/Counter modePKI_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_DecryptBytes, CIPHER_EncryptHex, CIPHER_DecryptHex, CIPHER_FileEncrypt and 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:

ValuePaddingOption
nopad[ding]No padding is addedPKI_PAD_NOPAD
pkcs5[padding]The padding scheme described in PKCS#5/#7 [PKCS5]PKI_PAD_PKCS5
oneandzeroes[padding]Pads with 0x80 followed by as many zero bytes necessary to fill the blockPKI_PAD_1ZERO
ansix923[padding]The padding scheme described in ANSI X9.23 [X9-23]PKI_PAD_AX923
w3c[padding]The padding scheme described in W3C Recommendation for XML encryption [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:

szAlgModePadAlternative Option value
tdea/cbc/pkcs5PKI_BC_TDEA+PKI_MODE_CBC+PKI_PAD_PKCS5
tdea/cbc/pkcs5paddingPKI_BC_TDEA+PKI_MODE_CBC+PKI_PAD_PKCS5
tdeacbcpkcs5PKI_BC_TDEA+PKI_MODE_CBC+PKI_PAD_PKCS5
aes128-ecb-oneandzeroesPKI_BC_AES128+PKI_MODE_ECB+PKI_PAD_1ZERO

[Contents] [Index]

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], which is the same as the padding method in section 6.3 of [CMS], section 10.3 of [PKCS7] and para 1.1 of [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 < NB. 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 < NB) 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]. If N padding bytes are required (1 < NB) 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] [Index]

Valid key and block sizes for block cipher algorithms

AlgorithmKey size (bytes)Block size (bytes)IV size (bytes)Valid ECB/CBC data lengths
Triple DES24888, 16, 24, 32, ..., 8i, ... bytes
AES-12816161616, 32, 48, 64, ..., 16i, ... bytes
AES-19224161616, 32, 48, 64, ..., 16i, ... bytes
AES-25632161616, 32, 48, 64, ..., 16i, ... bytes

[Contents] [Index]

Specifying the signature algorithm in a SIG_ function

The signature functions 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.

szAlgNameEquivalent 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] [Index]

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] and [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() function.
  2. Encode (encapsulate) this message digest in ISO 9796-1 format using RSA_EncodeMsg().
  3. Sign, i.e. encrypt with the private RSA key, using RSA_RawPrivate().

Specific changes to enable this:

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 page.

There are two steps:

  1. Encode (pad) the message into a block the same size as the key: ISO/IEC 9796-1 Formatting.
  2. Sign (encrypt) the block using RSA in a particular manner: RSA2 Signing.

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 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 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");

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] [Index]

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] 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.

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_MakeSigDataFromString, CMS_MakeSigDataFromSigValue, or CMS_MakeDetachedSig functions.

Some options:

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 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 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 function. This will work for all types of SignedData objects, not just the "certs-only" type.

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], which in turn refers to ESS [RFC2634] and [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]. If a CMS validator supports this attribute (which this Toolkit now does - see CMS_VerifySigData), then additional checks are made to protect against signature and message digest algorithm substitution attacks.

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_MakeEnvDataFromString, or 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]. 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)
Parameterktrikarikekripwri
certListcert[s]cert[s]"@kekri""@pwri"
cipherAlg
keyEncrAlgN/AN/AN/A
hashAlgN/A
advOpts
kdfAlgN/AN/AN/A
keyWrapAlgN/AN/A
keyStringN/Aukmkekstrpassword
countN/AN/AN/AiterCount

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]. 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] [Index]

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 function or Smime.Wrap method to create an S/MIME file from binary CMS signed-data, enveloped-data and compressed-data objects, and the SMIME_Extract function or Smime.Extract method to extract the body from an S/MIME file.

Sending an enveloped-data object

The output from the 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 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 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 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 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] and Examples of S/MIME Messages [SMIME-EX]. Stallings also covers the topic well in Cryptography and Network Security [STAL].

[Contents] [Index]

Using output in XML documents

You can create most of the cryptographic elements required in the [XML-DSIG] and [XML-ENC] specifications to insert into XML documents. These XML values should be encoded in base64 encoding. Use CNV_B64StrFromBytes or Cnv.ToBase64 to convert byte arrays into base64 encoding.

Here is a selection of some elements you can create.

SignatureValue element

Use Sig.SignData or Sig.SignFile.

Alternatively, use Rsa.EncodeMsgForSignature followed by Rsa.RawPrivate then Cnv.ToBase64.

DigestValue element

Use Hash.BytesFromBytes or Hash.BytesFromFile then Cnv.ToBase64.

X509Certificate element

Use X509.ReadStringFromFile.

X509IssuerSerial element

Use X509.QueryCert with query "serialNumber" and X509.OutputOpts.Decimal.

X509SubjectName element

Use X509.QueryCert with query "subjectName" and X509.OutputOpts.Ldap.

RSAKeyValue element

Use Rsa.KeyValue or Rsa.ToXMLString.

RSAKeyPair element

Use Rsa.ToXMLString.

CipherValue element

xmlenc#rsa-1_5: Use Rsa.EncodeMsgForEncryption with Rsa.EME.PKCSv1_5 option followed by Rsa.RawPublic then Cnv.ToBase64

xmlenc#rsa-oaep-mgf1p: As for xmlenc#rsa-1_5 except use Rsa.EME.OAEP option.

xmlenc#tripledes-cbc: Use Cipher.Encrypt with options CipherAlgorithm.Tdea, Mode.CBC and padding.Pkcs5, then Cnv.ToBase64.

xmlenc#aes128-cbc: As for xmlenc#tripledes-cbc except use CipherAlgorithm.Aes128 option.

xmlenc#aes192-cbc: As for xmlenc#tripledes-cbc except use CipherAlgorithm.Aes192 option.

xmlenc#aes256-cbc: As for xmlenc#tripledes-cbc except use CipherAlgorithm.Aes256 option.

[Contents] [Index]

Base64url encoding and JSON Web Signatures (JWS)

Use the optional PKI_ENCODE_BASE64URL option when creating a signature with SIG_SignData or Sig.SignData to output the signature value in base64url encoding suitable for inserting in a JSON Web Signature.

Base64url encoding is defined in [RFC7515] to use the URL- and filename-safe character set in section 5 of [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] [Index]

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 and 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:

In practice, there are rules to pad the input data before applying the RSA transformation.

Use the function RSA_EncodeMsg to encode or "pad" the message data you want to encrypt or sign. This uses the rules in [PKCS#1]. Then use the appropriate RSA_Raw function with the public or private RSA key.

To encrypt some data: use Rsa.EncodeMsgForEncryption with either the Rsa.EME.PKCSv1_5 option or the Rsa.EME.OAEP option, followed by Rsa.RawPublic. 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 followed by Rsa.RawPrivate. 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 and RSA_Decrypt to carry out RSA encryption and decryption more conveniently and securely in one step. In .NET use the Rsa.Encrypt and Rsa.Decrypt methods. To sign data in one step, use SIG_SignData (Sig.SignData Method). To verify a signature, use SIG_VerifyData (Sig.VerifyData Method).

[Contents] [Index]

RSA signature and encryption schemes: RSA-PSS and RSA-OAEP

There are two RSA signature schemes specified in [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.

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.

RSASSA-PSS parameters

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 parameters

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.

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] [Index]

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]. It makes use of the KEMRecipientInfo structure as specified in [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 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] [Index]

Elliptic curve Diffie-Hellman (ECDH)

[New in v20.0] Support is provided for Elliptic Curve Diffie-Hellman (ECDH) operations using the ECC_DHSharedSecret and .NET Ecc.DHSharedSecret Method.

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] and "ECSVDP-DHC" in [IEEE1363], and the latter as "ECSVDP-DH" in [IEEE1363] and [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].

[Contents] [Index]

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] and ChaCha20Poly1305 in [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], and [New in v22.0] using ChaCha20Poly1305 as in [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].

† Note that the term "IV" is used here to mean exactly the same as "nonce".

[Contents] [Index]

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]; namely Elliptic Curve Diffie-Hellman (ECDH) key agreement (see ECC_DHSharedSecret), HMAC-based key derivation function (HKDF) using SHA2 (see KDF_Bytes), and authenticated encryption with additional data (AEAD) (see CIPHER_EncryptAEAD).

Specific functions HPKE_LabeledExtract and HPKE_LabeledExpand are provided here to carry out LabeledExtract() and LabeledExpand(). The function 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.

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]).

KEMECDH groupKDF
DHKEM(P-256,
HKDF-SHA256
P-256HKDF-SHA256
DHKEM(P-384,
HKDF-SHA384
P-384HKDF-SHA384
DHKEM(P-521,
HKDF-SHA512
P-521HKDF-SHA512
DHKEM(X25519,
HKDF-SHA256
X25519HKDF-SHA256
DHKEM(X448,
HKDF-SHA512
X448HKDF-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] [Index]

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], available with HASH_Bytes. SHAKE128 and SHAKE256 are XOFs with security strengths of 128 bits and 256 bits respectively based on the SHA3 hash algorithm [FIPS202], available with XOF_Bytes.

The Mask Generation Function MGF1 described in [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] (see section 7.2.2, Hmsg); it is available with 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. 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]. 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

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], available with KDF_Bytes.

Thus we have a hierarchy KDF > PRF > MAC.

[Contents] [Index]

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 and Cross-reference between Functions and .NET Methods.

Index:   ASN.1 | Block Cipher | CMS | Conversion | Compression | CRL | ECC | General | Hash | HMAC | HPKE | KDF | OCSP | Padding | PBE | PEM files | PFX | PRF | Prompt | RNG | RSA Keys | RSA (Raw) | SIG | S/MIME | Triple DES (TDEA) | Wipe | X.509 Certificates | XOF

ASN.1 analysis functions

[Contents] [Index]

Block Cipher Functions

[Contents] [Index]

CMS functions

[Contents] [Index]

Conversion functions

The following functions are deprecated. Use the "Byte" versions instead:

[Contents] [Index]

Compression functions

[Contents] [Index]

Certificate Revocation List (CRL) functions

[Contents] [Index]

Elliptic curve cryptography functions

[Contents] [Index]

General functions

[Contents] [Index]

Message Digest Hash Functions

[Contents] [Index]

HMAC Functions

[Contents] [Index]

Hybrid Public Key Encryption (HPKE) functions

[Contents] [Index]

Key Derivation Functions

[Contents] [Index]

OCSP Functions

[Contents] [Index]

Padding functions

[Contents] [Index]

Password-based encryption functions

[Contents] [Index]

PEM/binary file conversion functions

[Contents] [Index]

PFX Functions

[Contents] [Index]

Pseudorandom functions (PRF)

[Contents] [Index]

Password prompt functions

[Contents] [Index]

Random number generator functions

[Contents] [Index]

RSA key functions

[Contents] [Index]

Raw RSA functions

[Contents] [Index]

SIG functions

[Contents] [Index]

S/MIME functions

[Contents] [Index]

Triple DES (TDEA/3DES) Functions

[Contents] [Index]

Wipe functions

[Contents] [Index]

X.509 certificate functions

[Contents] [Index]

eXtendable-output functions (XOF)

[Contents] [Index]

List of Functions

Index:   ASN.1 | Block Cipher | CMS | Conversion | Compression | CRL | ECC | General | Hash | HMAC | HPKE | KDF | OCSP | Padding | PBE | PEM files | PFX | PRF | Prompt | RNG | RSA Keys | RSA (Raw) | SIG | S/MIME | Triple DES (TDEA) | Wipe | X.509 Certificates | XOF

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 or PEM string).
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.

.NET Equivalent

Asn1.TextDump Method

C++ (STL) Equivalent

static int dipki::Asn1::TextDump (const std::string &outputFile, const std::string &asn1File, Opts opts=Opts::None)

Python Equivalent

static Asn1.text_dump(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 or as a PEM string. 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_Type

[Contents] [Index]

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 or PEM string).
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.

VBA Wrapper Syntax

Public Function asn1TextDumpToString (szFileOrPEMString As String, Optional nOptions As Long = 0, Optional szDirName As String = "") As String

.NET Equivalent

Asn1.TextDumpToString Method

C++ (STL) Equivalent

static std::string dipki::Asn1::TextDumpToString (const std::string &asn1File, Opts opts=Opts::None)

Python Equivalent

static Asn1.text_dump_tostring(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 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 or as a PEM string. 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

[Contents] [Index]

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 or PEM string).
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.

VBA Wrapper Syntax

Public Function asn1Type (szFileOrPEMString As String, Optional nOptions As Long = 0) As String

.NET Equivalent

Asn1.Type Method

C++ (STL) Equivalent

static std::string dipki::Asn1::Type (const std::string &asn1File)

Python Equivalent

static Asn1.type(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 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 or as a PEM string. 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 valueASN.1 object typeReference
EC PRIVATE KEY ECPrivateKey [RFC5915]
OCSP REQUEST OCSPRequest [RFC6960]
OCSP RESPONSE OCSPResponse [RFC6960]
PKCS1 RSA PRIVATE KEY RSAPrivateKey [RFC3447]
PKCS1 RSA PUBLIC KEY RSAPublicKey [RFC3447]
PKCS10 CERTIFICATE REQUEST CertificationRequest [RFC2986]
PKCS12 PFX PFX [RFC7292]
PKCS7 CERTIFICATE CHAIN ContentInfo [RFC5652]
PKCS7/CMS COMPRESSED DATA ContentInfo [RFC3274]
PKCS7/CMS DATA ContentInfo [RFC5652]
PKCS7/CMS ENVELOPED DATA ContentInfo [RFC5652]
CMS AUTH ENVELOPED DATA ContentInfo [RFC5083]
PKCS7/CMS SIGNED DATA ContentInfo [RFC5652]
PKCS8 ENCRYPTED PRIVATE KEYEncryptedPrivateKeyInfo[RFC5208], [RFC5958]
PKCS8 PRIVATE KEY INFOPrivateKeyInfo[RFC5208], [RFC5958]
PKCS8 ONE ASYMMETRIC KEYOneAsymmetricKey[RFC5958]
PUBLIC KEY INFOSubjectPublicKeyInfo[RFC3279], [RFC5480]
X509 CERTIFICATECertificate[RFC5280]
X509 CRLCertificateList[RFC5280]

Note that these descriptions are not necessarily those used as labels for PEM formatted files. See PEM_FileFromBinFile and [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 PEM_FileFromBinFile

[Contents] [Index]

CIPHER_Bytes

Encrypt or decrypt data in a byte array. The key and initialization vector are given as byte arrays.
@deprecated Use CIPHER_EncryptBytes or 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).
nOptions
[in] option flags.

Returns (VBA/C)

If successful, the return value is zero; otherwise it returns a nonzero error code.

.NET Equivalent

Cipher.Encrypt Method (Byte[], Byte[], Byte[], CipherAlgorithm, Mode)
Cipher.Decrypt Method (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). 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. 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 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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function cipherDecryptAEAD (lpInput() As Byte, lpKey() As Byte, lpIV() As Byte, lpAAD() As Byte, nOptions As Long) As Byte()

.NET Equivalent

Cipher.DecryptAEAD Method (Byte[], Byte[], Byte[], AeadAlgorithm)
Cipher.DecryptAEAD Method (Byte[], Byte[], Byte[], Byte[], AeadAlgorithm, Cipher.Opts)

C++ (STL) Equivalent

static bvec_t dipki::Cipher::DecryptAEAD (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(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

[Contents] [Index]

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).
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.

VBA Wrapper Syntax

Public Function 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 (Byte[], Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)

C++ (STL) Equivalent

static bvec_t dipki::Cipher::Decrypt (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 (const bvec_t &data, const bvec_t &key, const bvec_t &iv, const std::string algModePad, Opts opts=Opts::None)
static Cipher.decrypt_block(data, key, iv=None, alg=Alg.TDEA, mode=Mode.ECB)

Python Equivalent

static Cipher.decrypt(data, key, iv=None, algmodepad='', alg=None, mode=Mode.ECB, pad=Pad.DEFAULT, opts=Opts.DEFAULT)
static Cipher.decrypt_block(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). 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.

[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.

See Also

CIPHER_EncryptBytes

[Contents] [Index]

CIPHER_DecryptBytes2

@deprecated use CIPHER_DecryptBytes.

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).
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.

VBA Wrapper Syntax

Public Function 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 (String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts)

Python Equivalent

static Cipher.decrypt_hex(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 when allocating memory.

This is the equivalent of CIPHER_DecryptBytes with all parameters passed as hex-encoded strings instead of byte arrays. It is similar to the 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).

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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function cipherEncryptAEAD (lpInput() As Byte, lpKey() As Byte, lpIV() As Byte, lpAAD() As Byte, nOptions As Long) As Byte()

.NET Equivalent

Cipher.EncryptAEAD Method (Byte[], Byte[], Byte[], AeadAlgorithm)
Cipher.EncryptAEAD Method (Byte[], Byte[], Byte[], Byte[], AeadAlgorithm, Cipher.Opts)

C++ (STL) Equivalent

static bvec_t dipki::Cipher::EncryptAEAD (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(data, key, iv, aeadalg, aad=None, opts=Opts.DEFAULT)

Remarks

This function carries out authenticated encryption using AES-GCM. 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

[Contents] [Index]

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).
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.

VBA Wrapper Syntax

Public Function 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 (Byte[], Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)

C++ (STL) Equivalent

static bvec_t dipki::Cipher::Encrypt (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 (const bvec_t &data, const bvec_t &key, const bvec_t &iv, const std::string algModePad, Opts opts=Opts::None)
static Cipher.encrypt_block(data, key, iv=None, alg=Alg.TDEA, mode=Mode.ECB)

Python Equivalent

static Cipher.encrypt(data, key, iv=None, algmodepad='', alg=None, mode=Mode.ECB, pad=Pad.DEFAULT, opts=Opts.DEFAULT)
static Cipher.encrypt_block(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). 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.

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]) 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.

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

[Contents] [Index]

CIPHER_EncryptBytes2

@deprecated use CIPHER_EncryptBytes.

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).
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.

VBA Wrapper Syntax

Public Function 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 (String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts)

Python Equivalent

static Cipher.encrypt_hex(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 when allocating memory.

This is the equivalent of CIPHER_EncryptBytes with all parameters passed as hex-encoded strings instead of byte arrays. It is similar to the 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).

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]) 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

[Contents] [Index]

CIPHER_File

Encrypt or decrypt data in a file using the specified block cipher algorithm and mode.
@deprecated Use CIPHER_FileEncrypt() or 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).
nOptions
[in] option flags.

Returns (VBA/C)

If successful, the return value is zero; otherwise it returns a nonzero error code.

.NET Equivalent

Cipher.FileEncrypt Method
Cipher.FileDecrypt Method

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). 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. 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], which is the same as the padding method in [PKCS7] section 10.3 and [PKCS5] section 6.1.1 and [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_Hex

[Contents] [Index]

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).
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.

VBA Wrapper Syntax

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

.NET Equivalent

Cipher.FileDecrypt Method (String, String, Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)
Cipher.FileDecrypt Method (String, String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts)

C++ (STL) Equivalent

static int dipki::Cipher::FileDecrypt (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(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). 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. 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.

See Also

CIPHER_FileEncrypt

[Contents] [Index]

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).
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.

VBA Wrapper Syntax

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

.NET Equivalent

Cipher.FileEncrypt Method (String, String, Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)
Cipher.FileEncrypt Method (String, String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts)

C++ (STL) Equivalent

static int dipki::Cipher::FileEncrypt (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(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). 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. 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, 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]).

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

[Contents] [Index]

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).
nOptions
[in] option flags.

Returns (VBA/C)

If successful, the return value is zero; otherwise it returns a nonzero error code.

.NET Equivalent

Cipher.Encrypt Method (String, String, String, CipherAlgorithm, Mode)
Cipher.Decrypt Method (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). 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. 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 and 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_File CIPHER_EncryptHex CIPHER_DecryptHex

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function cipherKeyWrap (lpData() As Byte, lpKEK() As Byte, nOptions As Long) As Byte()

.NET Equivalent

Cipher.KeyWrap Method

C++ (STL) Equivalent

static bvec_t dipki::Cipher::KeyWrap (const bvec_t &data, const bvec_t &kek, Alg alg)

Python Equivalent

static Cipher.key_wrap(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] or the Triple-DES Key Wrap algorithm from [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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function cipherKeyUnwrap (lpData() As Byte, lpKEK() As Byte, nOptions As Long) As Byte()

.NET Equivalent

Cipher.KeyUnwrap Method

C++ (STL) Equivalent

static bvec_t dipki::Cipher::KeyUnwrap (const bvec_t &data, const bvec_t &kek, Alg alg)

Python Equivalent

static Cipher.key_unwrap(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] or the Triple-DES Key Wrap algorithm from [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

[Contents] [Index]

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.
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.

VBA Wrapper Syntax

Public Function cmsGetSigDataDigest (szFileIn As String, Optional szCertFile As String = "", Optional nOptions As Long = 0) As String

.NET Equivalent

Cms.GetSigDataDigest Method

C++ (STL) Equivalent

static std::string dipki::Cms::GetSigDataDigest (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 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:

CodeAlgorithm
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() and HASH_HexFromBytes(). VB6 users can use HASH_HexFromString. See the examples below.

Alternatively, use the CMS_VerifySigData() to verify the signature and message digest directly and use 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_ReadSigDataToString CMS_QuerySigData CMS_VerifySigData

[Contents] [Index]

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.

.NET Equivalent

Cms.MakeComprData Method

C++ (STL) Equivalent

static int dipki::Cms::MakeComprData (const std::string &outputFile, const std::string &inputFile)

Python Equivalent

static Cms.make_comprdata(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

[Contents] [Index]

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. Further error information may be available by calling PKI_LastError().

.NET Equivalent

Cms.MakeDetachedSig Method

C++ (STL) Equivalent

static int dipki::Cms::MakeDetachedSig (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(outputfile, hexdigest, certlist, prikeystr, sigalg=SigAlg.DEFAULT, opts=SigDataOpts.DEFAULT)

Remarks

RSASSA-PKCS1V1_5 only. See 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] 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_MakeSigDataFromString

[Contents] [Index]

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 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
[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).
PKI_KEM_RSA [New in v23.0] to encrypt the key using the RSA Key Encapsulation Mechanism (RSA-KEM) algorithm (see RSA-KEM).

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]
PKI_KDF_KDF2 to use KDF2 from ANSI-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.

VBA Wrapper Syntax

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

.NET Equivalent

Cms.MakeEnvData Method ( String, String, String, CipherAlgorithm, Cms.EnvDataOptions )
Cms.MakeEnvData Method ( 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 (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 (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(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. 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] and [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] and [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() 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]. 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_MakeEnvDataFromBytes

[Contents] [Index]

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 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
[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.

Returns (VBA/C)

If successful, the return value is the number of successful recipients; otherwise it returns a negative error code.

VBA Wrapper Syntax

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

.NET Equivalent

Cms.MakeEnvDataFromBytes Method

C++ (STL) Equivalent

static int dipki::Cms::MakeEnvDataFromBytes (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(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() 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 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_MakeEnvDataFromString CMS_ReadEnvDataToBytes

[Contents] [Index]

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 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
[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.

Returns (VBA/C)

If successful, the return value is the number of successful recipients; otherwise it returns a negative error code.

VBA Wrapper Syntax

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

.NET Equivalent

Cms.MakeEnvDataFromString Method (String, String, String, CipherAlgorithm, Cms.EnvDataOptions)
Cms.MakeEnvDataFromString Method (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 (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(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() above. Use this function only when the plaintext is only plain ASCII text, otherwise use 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_MakeEnvDataFromBytes

[Contents] [Index]

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. Further error information may be available by calling PKI_LastError().

.NET Equivalent

Cms.MakeSigData Method ( String, String, String, String, Cms.SigAlg, Cms.SigDataOptions)
Cms.MakeSigData Method ( String, String, String, String, HashAlgorithm, Cms.SigDataOptions)

C++ (STL) Equivalent

static int dipki::Cms::MakeSigData (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(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] and with ESS [RFC2634] and [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]. 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.

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].

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 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] but is allowed by PKCS#7 version 1.6 [PKCS7-EXT]. Some profiles (e.g. Royal Thai Customs) require this.

Example

This example duplicates example 4.2 from [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_MakeSigDataFromSigValue CMS_MakeDetachedSig

[Contents] [Index]

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())
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. Further error information may be available by calling PKI_LastError().

VBA Wrapper Syntax

Public Function 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
Cms.MakeSigDataFromPseudo Method

C++ (STL) Equivalent

static int dipki::Cms::MakeSigDataFromSigValue (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(outputfile, sigvalue, data, certlist, sigalg=SigAlg.DEFAULT, opts=SigDataOpts.DEFAULT)
static Cms.make_sigdata_from_pseudo(outputfile, inputfile, sigvalue, opts=SigDataOpts.DEFAULT)
static Cms.make_sigdata_from_pseudo(outputfile, inputfile, sigvalue, opts=SigDataOpts.DEFAULT)

Python Equivalent

static Cms.make_sigdata_from_sigvalue(outputfile, sigvalue, data, certlist, sigalg=SigAlg.DEFAULT, opts=SigDataOpts.DEFAULT)
static Cms.make_sigdata_from_pseudo(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 with the PKI_CMS_PSEUDOSIG option.

Example

This example creates an identical SignedData file to example 4.2 from [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_MakeDetachedSig

[Contents] [Index]

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. Further error information may be available by calling PKI_LastError().

VBA Wrapper Syntax

Public Function 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

C++ (STL) Equivalent

static int dipki::Cms::MakeSigDataFromBytes (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(outputfile, inputdata, certlist, prikeystr, sigalg=SigAlg.DEFAULT, opts=SigDataOpts.DEFAULT)

Python Equivalent

static Cms.make_sigdata_from_string(outputfile, inputstr, certlist, prikeystr, sigalg=SigAlg.DEFAULT, opts=SigDataOpts.DEFAULT)
static Cms.make_sigdata_from_bytes(outputfile, inputdata, certlist, prikeystr, sigalg=SigAlg.DEFAULT, opts=SigDataOpts.DEFAULT)

Remarks

This function is identical to CMS_MakeSigData() except the input is passed as a byte array instead of in a file. See the remarks for 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 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_MakeSigDataFromString CMS_MakeDetachedSig

[Contents] [Index]

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. Further error information may be available by calling PKI_LastError().

.NET Equivalent

Cms.MakeSigDataFromString Method (String, String, String, String, Cms.SigAlg, Cms.SigDataOptions)
Cms.MakeSigDataFromString Method (String, String, String, String, HashAlgorithm, Cms.SigDataOptions)

C++ (STL) Equivalent

static int dipki::Cms::MakeSigDataFromString (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() 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.

Example

nRet = CMS_MakeSigDataFromString(strOutputFile, "This is some sample content.", _
	strCertFile, strPrivateKey, 0)

See Also

CMS_MakeSigData CMS_MakeSigDataFromBytes CMS_MakeDetachedSig

[Contents] [Index]

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.
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.

VBA Wrapper Syntax

Public Function cmsQueryEnvData (szFileIn As String, szQuery As String, Optional nOptions As Long = 0) As String

.NET Equivalent

Cms.QueryEnvData Method

C++ (STL) Equivalent

static std::string dipki::Cms::QueryEnvData (const std::string &inputFile, const std::string &query)

Python Equivalent

static Cms.query_envdata(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 StringReturnsData Type
versionenvelopedData CMSVersion (edVer) valueNumber
recipientInfoVersionrecipientInfo version (riVer) valueNumber
recipientInfoTypeType of recipientInfo: ktri, kari, kekri, pwri, oriString
CountOfRecipientInfosNumber of RecipientInfos included in the dataNumber
recipientIssuerNameDistinguished Name of recipient's certificate issuerString
recipientSerialNumberserialNumber of recipient's certificate in hex formatString
keyEncryptionAlgorithmkeyEncryptionAlgorithm, e.g. "rsaEncryption"String
keyEncryptionFlagsBit flags used for the key encryption algorithm (ktri only)Number
SizeOfEncryptedKeySize (in bytes) of the EncryptedKeyNumber
encryptedKeyEncryptedKey value encoded in hexString
oaepParamsParameters used for RSA-OAEP (if applicable). String
kemParamsParameters used for RSA-KEM (if applicable) [New in v23.0] String
keyWrapAlgorithmKey wrap algorithm, e.g. "aes128-wrap" (kari and kekri only)String
originatorKeyAlgorithmOriginatorPublicKey algorithm, e.g. "ecPublicKey" (kari only)String
originatorPublicKeyOriginatorPublicKey publicKey value encoded in hex (kari only)String
keyidkeyIdentifier for KEKRecipientInfo (kekri) typeString
ukmUser Keying Material (if applicable) [New in v23.0]String
contentEncryptionAlgorithmcontentEncryptionAlgorithm, e.g. "des-EDE3-CBC"String
SizeOfEncryptedContentSize (in bytes) of the EncryptedContentNumber
encryptedContentEncryptedContent encoded in hexString
ivInitialization vector for encrypted content encoded in hexString
HASsubjectKeyIdentifier1 if recipientIdentifier is the CHOICE subjectKeyIdentifier; 0 if issuerAndSerialNumber [New in v23.0]Number
recipientIdentifierrecipientIdentifier 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 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

[Contents] [Index]

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.
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.

VBA Wrapper Syntax

Public Function cmsQuerySigData (szFileIn As String, szQuery As String, Optional nOptions As Long = 0) As String

.NET Equivalent

Cms.QuerySigData Method

C++ (STL) Equivalent

static std::string dipki::Cms::QuerySigData (const std::string &inputFile, const std::string &query)

Python Equivalent

static Cms.query_sigdata(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 StringReturnsData Type
versionsignedData version (sdVer) valueNumber
eContentTypeContentType of the EncapsulatedContentInfo, e.g. "data"String
HASeContent1 if eContent is present; 0 if notNumber
CountOfCertificatesNumber of certificates in the SignedDataNumber
CountOfSignerInfosNumber of SignerInfos in the SignedDataNumber
CountOfDigestAlgsNumber of DigestAlgorithmIdentifiers in the SignedData [New in v23.0]Number
certificate/NNth certificate encoded in base64 [New in v23.0]String
signerInfoVersionsignerInfo version (siVer) valueNumber
digestAlgorithmdigestAlgorithm, e.g. "sha1"String
signatureAlgorithmsignatureAlgorithm, e.g. "rsaEncryption"String
signatureValueSignature value encoded in hexString
HASsignedAttributes1 if signedAttributes (authenticatedAttributes) are present; 0 if notNumber
DigestOfSignedAttrsComputed digest over signed attributes, if present, using digestAlgorithmString
DigestOfeContentComputed digest over eContent, if present, using digestAlgorithmString
signingTimesigningTime attribute in format "2005-12-31 23:30:59"String
messageDigestmessageDigest attribute in hexadecimal format, if presentString
pssParamsParameters used for RSA-PSS (if applicable).String
HASsigningCertificate1 if an ESS signingCertificate is present; 0 if not.Number
signingCertHashcertHash value of ESS signing certificate, if present, encoded in hexString
HASalgorithmProtection1 if a cmsAlgorithmProtection attribute is present; 0 if not.Number
HASsubjectKeyIdentifier1 if signerIdentifier is the CHOICE subjectKeyIdentifier; 0 if issuerAndSerialNumber [New in v23.0]Number
signerIdentifiersignerIdentifier 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 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_GetSigDataDigest

[Contents] [Index]

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.

.NET Equivalent

Cms.ReadComprData Method

C++ (STL) Equivalent

static int dipki::Cms::ReadComprData (const std::string &outputFile, const std::string &inputFile, ComprDataOptions opts=ComprDataOptions::Default_ComprDataOpt)

Python Equivalent

static Cms.read_comprdata(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.

See Also

CMS_MakeComprData

[Contents] [Index]

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.
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.

.NET Equivalent

Cms.ReadEnvDataToFile Method

C++ (STL) Equivalent

static int dipki::Cms::ReadEnvDataToFile (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(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 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.

Use the PKI_CMS_BIGFILE option to process large files more efficiently. See the example in 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 above. Bob's private key needs to be read into a string first (see 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_MakeEnvDataFromString CMS_MakeEnvData

[Contents] [Index]

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.
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.

VBA Wrapper Syntax

Public Function cmsReadEnvDataToBytes (szFileIn As String, szCertFile As String, szPrivateKey As String, Optional nOptions As Long = 0) As Byte()

.NET Equivalent

Cms.ReadEnvDataToBytes Method

C++ (STL) Equivalent

static bvec_t dipki::Cms::ReadEnvDataToBytes (const std::string &inputFile, const std::string &privateKey, const std::string &certFile="")

Python Equivalent

static Cms.read_envdata_to_bytes(inputfile, prikeystr, certfile="")

Remarks

See the remarks for 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() 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 above. Bob's private key needs to be read into a string first (see 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_ReadEnvDataToBytes CMS_MakeEnvDataFromString CMS_MakeEnvData CMS_QueryEnvData

[Contents] [Index]

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.
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.

VBA Wrapper Syntax

Public Function cmsReadEnvDataToString (szFileIn As String, szCertFile As String, szPrivateKey As String, Optional nOptions As Long = 0) As String

.NET Equivalent

Cms.ReadEnvDataToString Method

Python Equivalent

static Cms.read_envdata_to_string(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 when allocating memory.

See the remarks for CMS_ReadEnvData() above. Alternatively, use the 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.

Example (VBA core function)

The following example reads the file created with CMS_MakeEnvData above. Bob's private key needs to be read into a string first (see 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_ReadEnvDataToBytes CMS_MakeEnvDataFromString CMS_MakeEnvData CMS_QueryEnvData

[Contents] [Index]

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.
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.

.NET Equivalent

Cms.ReadSigDataToFile Method

C++ (STL) Equivalent

static int dipki::Cms::ReadSigDataToFile (const std::string &outputFile, const std::string &inputFile, bool bigFile=false)

Python Equivalent

static Cms.read_sigdata_to_file(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] 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 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_GetSigDataDigest

[Contents] [Index]

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.
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.

VBA Wrapper Syntax

Public Function cmsReadSigDataToBytes (szFileIn As String, Optional nOptions As Long = 0) As Byte()

.NET Equivalent

Cms.ReadSigDataToBytes Method

C++ (STL) Equivalent

static bvec_t dipki::Cms::ReadSigDataToBytes (const std::string &inputFile)

Python Equivalent

static Cms.read_sigdata_to_bytes(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.

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_ReadSigDataToString CMS_GetSigDataDigest

[Contents] [Index]

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.
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.

VBA Wrapper Syntax

Public Function cmsReadSigDataToString (szFileIn As String, Optional nOptions As Long = 0) As String

.NET Equivalent

Cms.ReadSigDataToString Method

Python Equivalent

static Cms.read_sigdata_to_string(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 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.

Example (VBA core function)

This example reads the content from the signed CMS object from example 4.2 in [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_ReadSigDataToBytes CMS_GetSigDataDigest

[Contents] [Index]

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.
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.

VBA Wrapper Syntax

Public Function cmsVerifySigData (szFileIn As String, Optional szCertFile As String = "", Optional szHexDigest As String = "", Optional nOptions As Long = 0) As Long

.NET Equivalent

Cms.VerifySigData Method

C++ (STL) Equivalent

static bool dipki::Cms::VerifySigData (const std::string &inputFile, const std::string &certFile="", const std::string &hexDigest="", bool bigFile=false)

Python Equivalent

static Cms.verify_sigdata(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] and 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]. 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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function cnvB64Filter (szB64 As String) As String

.NET Equivalent

Cnv.Base64Filter Method

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 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_BytesFromB64Str

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function cnvB64StrFromBytes (lpData() As Byte) As String
Public Function cnvB64StrFromHexStr (szHex As String) As String
Public Function cnvB64StrFromString (szData As String) As String
Public Function cnvToBase64 (lpData() As Byte) As String

.NET Equivalent

Cnv.ToBase64 Method (Byte[])
Cnv.ToBase64 Method (String)

C++ (STL) Equivalent

static std::string dipki::Cnv::ToBase64 (const bvec_t &bv)
static std::string dipki::Cnv::ToBase64 (const std::string &s)

Python Equivalent

static Cnv.tobase64(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 when allocating memory.

This uses the base64 encoding scheme from [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_B64Filter

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function cnvBase58FromBytes (lpInput() As Byte) As String

.NET Equivalent

Cnv.ToBase58 Method

C++ (STL) Equivalent

static std::string dipki::Cnv::ToBase58 (const bvec_t &bv)

Python Equivalent

static Cnv.tobase58(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 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].

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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function cnvBase58ToBytes (szInput As String) As Byte()

.NET Equivalent

Cnv.FromBase58 Method

C++ (STL) Equivalent

static bvec_t dipki::Cnv::FromBase58 (const std::string &s)

Python Equivalent

static Cnv.frombase58(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]. 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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function cnvByteEncoding (lpInput() As Byte, nOptions As Long) As Byte()

.NET Equivalent

Cnv.ByteEncoding Method

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_Latin1FromUTF8Bytes CNV_CheckUTF8Bytes

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function cnvBytesFromB64Str (szB64 As String) As Byte()
Public Function cnvFromBase64 (strBase64 As String) As Byte()

.NET Equivalent

Cnv.FromBase64 Method

C++ (STL) Equivalent

static bvec_t dipki::Cnv::FromBase64 (const std::string &s)

Python Equivalent

static Cnv.frombase64(s)

Remarks

This uses the base64 encoding scheme from [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_B64Filter

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function cnvBytesFromHexStr (szHex As String) As Byte()
Public Function cnvFromHex (strHex As String) As Byte()
Public Function cnvStringFromHexStr (ByVal szHex As String) As String

.NET Equivalent

Cnv.FromHex Method

C++ (STL) Equivalent

static bvec_t dipki::Cnv::FromHex (const std::string &s)

Python Equivalent

static Cnv.fromhex(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_HexFilter

[Contents] [Index]

CNV_CheckUTF8

Checks if a string only contains valid UTF-8 characters.
@deprecated Use 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 (const bvec_t &bv)

Remarks

Example

See Also

[Contents] [Index]

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 (lpInput() As Byte) As Long

.NET Equivalent

Cnv.CheckUTF8 Method (Byte[])

Python Equivalent

static Cnv.utf8_check(data)

Remarks

Return values:

ReturnsValueResult
PKI_CHRS_NOT_UTF80Not valid UTF-8
PKI_CHRS_ALL_ASCII1Valid UTF-8, all chars are 7-bit ASCII
PKI_CHRS_ANSI82Valid UTF-8, contains at least one multi-byte character equivalent to 8-bit ANSI
PKI_CHRS_MULTIBYTE3Valid 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() 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.

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_Latin1FromUTF8Bytes CNV_UTF8BytesFromLatin1 CNV_ByteEncoding

[Contents] [Index]

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() for more details. If there is an error, like the file is missing or cannot be read, then it returns a negative error code.

.NET Equivalent

Cnv.CheckUTF8File Method

C++ (STL) Equivalent

static int dipki::Cnv::CheckUTF8File (const std::string &fileName)

Python Equivalent

static Cnv.utf8_check_file(filename)

Remarks

This is the same as CNV_CheckUTF8Bytes() but for a file instead of a byte array. For more details, see 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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function cnvHexFilter (szHex As String) As String

.NET Equivalent

Cnv.HexFilter Method

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 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_BytesFromHexStr

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function cnvHexFromBytesMid (abData() As Byte, nOffset As Long, nBytes As Long) As String
Public Function cnvHexStrFromB64Str (szB64 As String) As String
Public Function cnvHexStrFromBytes (lpData() As Byte) As String
Public Function cnvHexStrFromString (szData As String) As String
Public Function cnvToHex (lpData() As Byte) As String

.NET Equivalent

Cnv.ToHex Method

C++ (STL) Equivalent

static std::string dipki::Cnv::ToHex (const bvec_t &bv)
static std::string dipki::Cnv::ToHex (const std::string &s)

Python Equivalent

static Cnv.tohex(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 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_HexFilter

[Contents] [Index]

CNV_Latin1FromUTF8

Converts a UTF-8 string into a Latin-1 string, if possible.
@deprecated Use 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.

.NET Equivalent

Not applicable in .NET.

Remarks

Example

See Also

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function cnvLatin1FromUTF8Bytes (lpInput() As Byte) As String

.NET Equivalent

Use System.Text.Encoding.UTF8.GetString(bytes).

C++ (STL) Equivalent

static std::string dipki::Cnv::Latin1FromUTF8Bytes (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 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.

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_CheckUTF8Bytes CNV_ByteEncoding

[Contents] [Index]

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 (lpInput() As Byte, Optional nOptions As Long = 0) As Long

.NET Equivalent

Cnv.NumFromBytes Method

C++ (STL) Equivalent

static uint32_t dipki::Cnv::NumFromBytes (const bvec_t &bv, EndianNess endn=EndianNess::BigEndian)

Python Equivalent

static Cnv.num_from_bytes(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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function cnvNumToBytes (nNumber As Long, Optional nOptions As Long = 0) As Byte()

.NET Equivalent

Cnv.NumToBytes Method

C++ (STL) Equivalent

static bvec_t dipki::Cnv::NumToBytes (uint32_t n, EndianNess endn=EndianNess::BigEndian)

Python Equivalent

static Cnv.num_to_bytes(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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function cnvReverseBytes (lpInput() As Byte) As Byte()

.NET Equivalent

Cnv.ReverseBytes Method

C++ (STL) Equivalent

static bvec_t dipki::Cnv::ReverseBytes (const bvec_t &data)

Python Equivalent

static Cnv.reverse_bytes(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] [Index]

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.

.NET Equivalent

Cnv.ShortPathName Method

C++ (STL) Equivalent

static std::string dipki::Cnv::ShortPathName (const std::wstring &filePath)

Python Equivalent

static Cnv.shortpathname(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 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] [Index]

CNV_UTF8FromLatin1

Converts a string of 8-bit Latin-1 characters into UTF-8 format
@deprecated Use 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.

.NET Equivalent

Not applicable in .NET.

Remarks

Example

See Also

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function cnvUTF8BytesFromLatin1 (szInput As String) As Byte()

.NET Equivalent

Use System.Text.Encoding.UTF8.GetBytes(Str).

C++ (STL) Equivalent

static bvec_t dipki::Cnv::UTF8BytesFromLatin1 (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_CheckUTF8Bytes

[Contents] [Index]

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.

.NET Equivalent

No .NET equivalent.

C++ (STL) Equivalent

static std::string dipki::Cnv::Utf8FromWide (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] [Index]

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.

VBA Wrapper Syntax

Public Function comprCompress (lpInput() As Byte, Optional nOptions As Long = 0) As Byte()

.NET Equivalent

Compr.Compress Method

C++ (STL) Equivalent

static bvec_t dipki::Compr::Compress (const bvec_t &data)

Python Equivalent

static Compr.compress(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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function comprUncompress (lpInput() As Byte, Optional nOptions As Long = 0) As Byte()

.NET Equivalent

Compr.Uncompress Method

C++ (STL) Equivalent

static bvec_t dipki::Compr::Uncompress (const bvec_t &data)

Python Equivalent

static Compr.uncompress(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.

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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function eccDHSharedSecret (szIntPrivateKey As String, szIntPublicKey As String, Optional nOptions As Long = 0) As Byte()

.NET Equivalent

Ecc.DHSharedSecret Method

C++ (STL) Equivalent

static bvec_t dipki::Ecc::DHSharedSecret (std::string ourIntPrivateKey, std::string theirIntPublicKey)

Python Equivalent

static Ecc.dh_shared_secret(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_ReadPublicKey or 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] [Index]

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 (szIntKeyString As String) As Long

.NET Equivalent

Ecc.KeyHashCode Method

C++ (STL) Equivalent

static uint32_t dipki::Ecc::KeyHashCode (std::string intKeyString)

Python Equivalent

static Ecc.key_hashcode(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 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] [Index]

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 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)
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.

VBA Wrapper Syntax

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

.NET Equivalent

Ecc.MakeKeys Method

C++ (STL) Equivalent

static int dipki::Ecc::MakeKeys (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(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 nameAlternative namesRemarks
secp192r1P-192, P_192, prime192v1NIST
secp256r1P-256, P_256, prime256v1NIST
secp224r1P-224, P_224NIST
secp384r1P-384, P_384NIST
secp521r1P-521, P_521NIST
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:

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] [Index]

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.

VBA Wrapper Syntax

Public Function eccPublicKeyFromPrivate (szIntKeyString As String, Optional nOptions As Long = 0) As String

.NET Equivalent

Ecc.PublicKeyFromPrivate Method

C++ (STL) Equivalent

static std::string dipki::Ecc::PublicKeyFromPrivate (std::string internalKey)

Python Equivalent

static Ecc.publickey_from_private(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 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_ReadPublicKey

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function eccQueryKey (szIntKeyString As String, szQuery As String, Optional nOptions As Long = 0) As String

.NET Equivalent

Ecc.QueryKey Method

C++ (STL) Equivalent

static std::string dipki::Ecc::QueryKey (std::string internalKey, std::string query)

Python Equivalent

static Ecc.query_key(intkeystr, query)

Remarks

Valid queries are (case-insensitive):

Query StringReturnsData Type
curveNameName of the curveString
keyBitsNumber of bits in the keyNumber
isPrivate1 if the key is a private key; 0 if notNumber
isValid1 if the key is valid; 0 if notNumber
privateKeyValue of the private key in hex formatString
publicKeyValue of the public key in hex formatString

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 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_ReadPublicKey

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function eccReadKeyByCurve (szHexKey As String, szCurveName As String, Optional nOptions As Long = 0) As String

.NET Equivalent

Ecc.ReadKeyByCurve Method

C++ (STL) Equivalent

static std::string dipki::Ecc::ReadKeyByCurve (std::string hexKey, Curve curve, Publicity publicity=Publicity::PrivateKey)

Python Equivalent

static Ecc.read_key_by_curve(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 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 or SIG_SignData. You can analyze the key string using ECC_QueryKey or save it in one of the supported key file formats using ECC_SaveKey or 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]. A public key is represented by the hexadecimal encoding of the octet string as defined in section 4.3.6 of [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] and [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 nameAlternative namesRemarks
secp192r1P-192, P_192, prime192v1NIST
secp224r1P-224, P_224NIST
secp256r1P-256, P_256, prime256v1NIST
secp384r1P-384, P_384NIST
secp521r1P-521, P_521NIST
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

[Contents] [Index]

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.
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.

VBA Wrapper Syntax

Public Function eccReadPrivateKey (szKeyFileOrString As String, Optional szPassword As String = "", Optional nOptions As Long = 0) As String

.NET Equivalent

Ecc.ReadPrivateKey Method

C++ (STL) Equivalent

static std::string dipki::Ecc::ReadPrivateKey (std::string keyFileOrString, std::string password="")

Python Equivalent

static Ecc.read_private_key(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 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_QueryKey

[Contents] [Index]

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.
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.

VBA Wrapper Syntax

Public Function eccReadPublicKey (szKeyFileOrString As String, Optional nOptions As Long = 0) As String

.NET Equivalent

Ecc.ReadPublicKey Method

C++ (STL) Equivalent

static std::string dipki::Ecc::ReadPublicKey (std::string keyFileOrString)

Python Equivalent

static Ecc.read_public_key(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 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).

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_QueryKey

[Contents] [Index]

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
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)
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.

VBA Wrapper Syntax

Public Function 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

C++ (STL) Equivalent

static int dipki::Ecc::SaveEncKey (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(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:

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_SaveKey

[Contents] [Index]

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 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.

VBA Wrapper Syntax

Public Function eccSaveKey (szOutputFile As String, szKeyStr As String, Optional nOptions As Long = 0) As Long

.NET Equivalent

Ecc.SaveKey Method

C++ (STL) Equivalent

static int dipki::Ecc::SaveKey (std::string outputFile, std::string internalKey, KeyType keyType=KeyType::Default, Format fileFormat=Format::Binary)

Python Equivalent

static Ecc.save_key(outputfile, intkeystr, keytype=0, fileformat=0)

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].

[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]. 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 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_ReadPublicKey ECC_SaveEncKey ECC_PublicKeyFromPrivate

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function hashBytes (lpMessage() As Byte, nOptions As Long) As Byte()

.NET Equivalent

Hash.BytesFromBytes Method
Hash.Double Method

C++ (STL) Equivalent

static bvec_t dipki::Hash::Bytes (const bvec_t &data, Alg alg=Alg::Sha1)
static Hash.double(data, alg=Alg.SHA1)

Python Equivalent

static Hash.data(data, alg=Alg.SHA1)
static Hash.double(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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function hashFile (szFileName As String, nOptions As Long) As Byte()

.NET Equivalent

Hash.BytesFromFile Method

C++ (STL) Equivalent

static bvec_t dipki::Hash::File (const std::string &fileName, Alg alg=Alg::Sha1, FileMode mode=FileMode::Binary)

Python Equivalent

static Hash.file(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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function hashHexFromBytes (lpMessage() As Byte, nOptions As Long) As String

.NET Equivalent

Hash.HexFromBytes Method
Hash.HexFromString Method

C++ (STL) Equivalent

static std::string dipki::Hash::HexFromBytes (const bvec_t &data, Alg alg=Alg::Sha1)

Python Equivalent

static Hash.hex_from_data(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 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_Bytes

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function hashHexFromFile (szFileName As String, nOptions As Long) As String

.NET Equivalent

Hash.HexFromFile Method
Hash.HexFromTextFile Method

C++ (STL) Equivalent

static std::string dipki::Hash::HexFromFile (const std::string &fileName, Alg alg=Alg::Sha1, FileMode mode=FileMode::Binary)

Python Equivalent

static Hash.hex_from_file(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 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_File

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function hashHexFromHex (szMsgHex As String, nOptions As Long) As String

.NET Equivalent

Hash.HexFromHex Method

C++ (STL) Equivalent

static std::string dipki::Hash::HexFromHex (const std::string &dataHex, Alg alg=Alg::Sha1)

Python Equivalent

static Hash.hex_from_hex(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 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_Bytes

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function hashLength (nAlgId As Long) As Long

.NET Equivalent

Hash.Length Method

C++ (STL) Equivalent

static int dipki::Hash::Length (Alg alg)

Python Equivalent

static Hash.length(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] [Index]

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.

VBA Wrapper Syntax

Public Function hmacBytes (lpMessage() As Byte, lpKey() As Byte, nOptions As Long) As Byte()

.NET Equivalent

Hmac.BytesFromBytes Method

C++ (STL) Equivalent

static bvec_t dipki::Hmac::Bytes (const bvec_t &data, const bvec_t &key, Alg alg=Alg::Sha1)

Python Equivalent

static Hmac.data(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_HexFromHex

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function hmacHexFromBytes (lpMessage() As Byte, lpKey() As Byte, nOptions As Long) As String

.NET Equivalent

Hmac.HexFromBytes Method

C++ (STL) Equivalent

static std::string dipki::Hmac::HexFromBytes (const bvec_t &data, const bvec_t &key, Alg alg=Alg::Sha1)

Python Equivalent

static Hmac.hex_from_data(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 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_HexFromHex

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function hmacHexFromHex (szMsgHex As String, szKeyHex As String, nOptions As Long) As String

.NET Equivalent

Hmac.HexFromHex Method

C++ (STL) Equivalent

static std::string dipki::Hmac::HexFromHex (const std::string &dataHex, const std::string &keyHex, Alg alg=Alg::Sha1)

Python Equivalent

static Hmac.hex_from_hex(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 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_HexFromBytes

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function hpkeDerivePrivateKey (lpIkm() As Byte, szCurveName As String, Optional nOptions As Long = 0) As String

.NET Equivalent

Hpke.DerivePrivateKey Method

C++ (STL) Equivalent

static std::string dipki::Hpke::DerivePrivateKey (const bvec_t &ikm, CurveName curve, OutputOpts opts=OutputOpts::Default)

Python Equivalent

static Hpke.derive_private_key(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_SaveEncKey, ECC_PublicKeyFromPrivate, ECC_DHSharedSecret and 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] (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 when allocating memory.

This function derives an ECDH private key in the deterministic manner described in [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 groupNsk
P-25632
P-38448
P-52166
X2551932
X44856

The KDF to be used is fixed by the EC curve group. See Hybrid Public Key Encryption (HPKE).

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] [Index]

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.

VBA Wrapper Syntax

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()

.NET Equivalent

Hpke.LabeledExpand Method

C++ (STL) Equivalent

static bvec_t dipki::Hpke::LabeledExpand (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(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]. It uses the "expand" stage of the HKDF function [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]. 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).

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

[Contents] [Index]

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. otherwise it returns a negative error code.

VBA Wrapper Syntax

Public Function 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

C++ (STL) Equivalent

static bvec_t dipki::Hpke::LabeledExtract (const bvec_t &salt, std::string label, const bvec_t &ikm, CurveName curve, AeadAlg aeadAlg=AeadAlg::None)

Python Equivalent

static Hpke.labeled_extract(salt, label, ikm, curveName, aeadalg=AeadAlg.NONE)

Remarks

The LabeledExtract function is defined in section 4 of [RFC9180]. It uses the "extract" stage of the HKDF function [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]. 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).

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

[Contents] [Index]

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
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.

VBA Wrapper Syntax

Public Function 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

C++ (STL) Equivalent

static bvec_t dipki::Kdf::Bytes (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(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]. The HMAC-based Key Derivation Function (HKDF) is described in [RFC5869]. KDF2 and KDF3 are described in ANSI 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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function kdfForCms (lpZZ() As Byte, lpUkm() As Byte, Optional nOptions As Long = 0) As Byte()

.NET Equivalent

Kdf.ForCms Method

C++ (STL) Equivalent

static bvec_t dipki::Kdf::ForCms (const bvec_t &zz, KeyWrapAlg keyWrapAlg, KdfAlg kdfAlg=KdfAlg::X963, HashAlg hashAlg=HashAlg::Sha1, const bvec_t &ukm={})

Python Equivalent

static Kdf.for_cms(zz, keywrapalg, kdfalg=KdfAlg.X963, hashalg=HashAlg.SHA1, ukm=None)

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.

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] (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] (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

[Contents] [Index]

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).
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.

VBA Wrapper Syntax

Public Function ocspMakeRequest (szIssuerCert As String, szCertFileOrSerialNum As String, nOptions As Long, Optional szExtensions As String = "") As String

.NET Equivalent

Ocsp.MakeRequest Method

C++ (STL) Equivalent

static std::string dipki::Ocsp::MakeRequest (const std::string &issuerCert, const std::string &certFileOrSerialNumber, HashAlg hashAlg=HashAlg::Sha1)

Python Equivalent

static Ocsp.make_request(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 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() 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

[Contents] [Index]

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).
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.

VBA Wrapper Syntax

Public Function ocspReadResponse (szResponseFile As String, Optional szIssuerCert As String = "", Optional nOptions As Long = 0, Optional szExtensions As String = "") As String

.NET Equivalent

Ocsp.ReadResponse Method

C++ (STL) Equivalent

static std::string dipki::Ocsp::ReadResponse (const std::string &responseFile, const std::string &issuerCert="")

Python Equivalent

static Ocsp.read_response(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 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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function padBytesBlock (lpInput() As Byte, nBlkLen As Long, Optional nOptions As Long = 0) As Byte()

.NET Equivalent

Cipher.Pad Method

C++ (STL) Equivalent

static bvec_t dipki::Cipher::Pad (const bvec_t &input, Alg alg, Padding pad=Padding::Pkcs5)

Python Equivalent

static Cipher.pad(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_HexBlock PAD_UnpadHex

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function 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 (String, CipherAlgorithm, Padding)

Python Equivalent

static Cipher.pad_hex(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 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_BytesBlock PAD_UnpadBytes

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function 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 (Byte[], CipherAlgorithm, Padding)

C++ (STL) Equivalent

static bvec_t dipki::Cipher::Unpad (const bvec_t &input, Alg alg, Padding pad=Padding::Pkcs5)

Python Equivalent

static Cipher.unpad(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_HexBlock PAD_UnpadHex

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function 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 (String, CipherAlgorithmPadding)

Python Equivalent

static Cipher.unpad_hex(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 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.

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_BytesBlock PAD_UnpadBytes

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function 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 (Int32, Byte[], Byte[], Int32, HashAlgorithm)

C++ (STL) Equivalent

static bvec_t dipki::Pbe::Kdf2 (int dklen, const std::string password, const bvec_t &salt, int count, PrfAlg prfalg=PrfAlg::Hmac_Sha1)

Python Equivalent

static Pbe.kdf2(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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function 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 (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 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

[Contents] [Index]

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.

VBA Wrapper Syntax

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()

.NET Equivalent

Pbe.Scrypt Method (Int32, Byte[], Byte[], Int32, Int32, Int32)

C++ (STL) Equivalent

static bvec_t dipki::Pbe::Scrypt (int dklen, const std::string password, const bvec_t &salt, int N, int r, int p)

Python Equivalent

static Pbe.scrypt(dklen, pwdbytes, salt, N, r, p)

Remarks

This uses the SCRYPT algorithm from [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].

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

[Contents] [Index]

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.

VBA Wrapper Syntax

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

.NET Equivalent

Pbe.Scrypt Method (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

[Contents] [Index]

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.

.NET Equivalent

Pem.FileFromBinFile Method Pem.FileFromBinFile Method

C++ (STL) Equivalent

static int dipki::Pem::FileFromBinFile (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 HeaderType of fileTypical file extensionsComment
CERTIFICATEX.509 certificate.cer,.der,.pem,.crtShould contain exactly one certificate
CERTIFICATE REQUESTPKCS#10 certificate signing request.csr,.p10 
X509 CRLX.509 certificate revocation list.crl 
PKCS12PFX file to PKCS#12.p12,.pfx 
ENCRYPTED PRIVATE KEYPKCS#8 key.p8e,.key,(.epk)Our default private key format
RSA PUBLIC KEYPKCS#1 public key.p1,.pubOur default public key format
PUBLIC KEYSubjectPublicKeyInfo OpenSSL format (PKI_KEY_FORMAT_SSL)
PRIVATE KEYUnencrypted PKCS#8 private key info.p8,.pri,.keyOur private key info format
RSA PRIVATE KEYUnencrypted PKCS#1 private key OpenSSL format (PKI_KEY_FORMAT_SSL)
PKCS7CMS object to PKCS#7.p7m,.p7s,.p7c,.p7b,.p7zUsed by OpenSSL
PKCS #7 SIGNED DATAditto Used by Thawte for Microsoft users
NETSCAPE CERTIFICATE CHAIN"certs-only" PKCS#7.p7c,.p7bUsed by Thawte for Netscape users

Update April 2015: see RFC 7468 "Textual Encodings of PKIX, PKCS, and CMS Structures" [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_FileToBinFile

[Contents] [Index]

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.

.NET Equivalent

Pem.FileFromBinFile Method Pem.FileFromBinFile Method

Python Equivalent

static Pem.from_binfile(outputfile, filein, header, linelen=64, eol=EOL.DEFAULT)

Remarks

See the remarks for 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_FileToBinFile

[Contents] [Index]

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.

.NET Equivalent

Pem.FileToBinFile Method

C++ (STL) Equivalent

static int dipki::Pem::FileToBinFile (const std::string &fileToMake, const std::string &fileIn)

Python Equivalent

static Pem.to_binfile(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

[Contents] [Index]

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) 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). 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.

VBA Wrapper Syntax

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

.NET Equivalent

Pfx.MakeFile Method

C++ (STL) Equivalent

static int dipki::Pfx::MakeFile (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(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]. 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 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 RSA_GetPrivateKeyFromPFX RSA_ReadPrivateKeyFromPFX

[Contents] [Index]

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.

.NET Equivalent

Pfx.SignatureIsValid Method

Python Equivalent

static Pfx.sig_is_valid(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 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 above.

See Also

PFX_MakeFile RSA_GetPrivateKeyFromPFX

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function pkiCompileTime() As String

.NET Equivalent

General.CompileTime Method

C++ (STL) Equivalent

static std::string dipki::Gen::CompileTime ()

Python Equivalent

static Gen.compile_time()

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 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

[Contents] [Index]

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 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() As Long

.NET Equivalent

General.ErrorCode Method

Python Equivalent

static Gen.error_code()

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() will indicate the error code for the invalid certificate. PKI_LastError() should have a more detailed error message.

Example

   Dim nErrCode as Long
   nErrCode = PKI_ErrorCode()

See Also

PKI_LastError PKI_ErrorLookup Error codes

[Contents] [Index]

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 (nErrCode As Long) As String

.NET Equivalent

General.ErrorLookup Method

C++ (STL) Equivalent

static std::string dipki::Err::ErrorLookup (int errCode)

Python Equivalent

static Gen.error_lookup(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 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 Error codes

[Contents] [Index]

PKI_FormatErrorMessage

Return a formatted error message string for the last error.

VBA/VB6 Syntax

No direct call from VBA/VB6. Use 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

C++ (STL) Equivalent

static std::string dipki::Err::FormatErrorMessage (int errCode=0, const std::string &userMsg="")

Remarks

This is a combination of PKI_ErrorLookup, PKI_ErrorCode and 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_ErrorCode PKI_LastError Error codes

[Contents] [Index]

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 when allocating memory.

VBA Wrapper Syntax

Public Function pkiLastError() As String

.NET Equivalent

General.LastError Method

C++ (STL) Equivalent

static std::string dipki::Err::LastError ()

Python Equivalent

static Gen.last_error()

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_ErrorLookup Error codes

[Contents] [Index]

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 (Optional nOptions As Long = 0) As String

.NET Equivalent

General.LicenceType Method

C++ (STL) Equivalent

static std::string dipki::Gen::LicenceType ()

Python Equivalent

static Gen.licence_type()

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_CompileTime

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function pkiModuleInfo (Optional nOptions As Long = 0) As String

.NET Equivalent

General.ModuleInfo Method

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] [Index]

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.

VBA Wrapper Syntax

Public Function pkiModuleName (Optional nOptions As Long = 0) As String

.NET Equivalent

General.ModuleName Method

C++ (STL) Equivalent

static std::string dipki::Gen::ModuleName ()

Python Equivalent

static Gen.module_name()

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 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 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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function pkiPlatform() As String

.NET Equivalent

General.Platform Method

C++ (STL) Equivalent

static std::string dipki::Gen::Platform ()

Python Equivalent

static Gen.core_platform()

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 when allocating memory.

Example (VBA wrapper function)

Debug.Print pkiCompileTime()
Debug.Print pkiModuleInfo()
Debug.Print pkiModuleName()
Debug.Print pkiPlatform()

See Also

PKI_ModuleName

[Contents] [Index]

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.

.NET Equivalent

General.PowerUpTests Method

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. 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

[Contents] [Index]

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() As Long

.NET Equivalent

General.Version Method

C++ (STL) Equivalent

static int dipki::Gen::Version ()

Python Equivalent

static Gen.version()

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_CompileTime

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function prfBytes (nBytes As Long, lpMessage() As Byte, lpKey() As Byte, nOptions As Long, Optional szCustom As String = "") As Byte()

.NET Equivalent

Prf.Bytes Method

C++ (STL) Equivalent

static bvec_t dipki::Prf::Bytes (int numBytes, const bvec_t &message, const bvec_t &key, PrfAlg prfalg, const std::string &customStr="")

Python Equivalent

static Prf.bytes(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

[Contents] [Index]

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 (Optional szCaption As String = "", Optional szPrompt As String = "") As String

.NET Equivalent

Pwd.Prompt Method

C++ (STL) Equivalent

static std::string dipki::Pwd::Prompt (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 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().

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

[Contents] [Index]

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

Python Equivalent

static Pwd.prompt(caption="", prompt="")

Remarks

See 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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function rngBytes (nBytes As Long) As Byte()

.NET Equivalent

Rng.Bytes Method (Int32)
Rng.Bytes Method (Int32, Byte)
Rng.Bytes Method (Int32, String)

C++ (STL) Equivalent

static bvec_t dipki::Rng::Bytes (int n)

Python Equivalent

static Rng.bytestring(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 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_Number

[Contents] [Index]

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.

.NET Equivalent

Rng.BytesWithPrompt Method (Int32, Rng.Strength)
Rng.BytesWithPrompt Method (Int32, String, Rng.Strength)

Python Equivalent

static Rng.bytes_with_prompt(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 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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function rngGuid() As String

.NET Equivalent

Rng.Guid Method

C++ (STL) Equivalent

static std::string dipki::Rng::Guid ()

Python Equivalent

static Rng.guid()

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 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]. 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] [Index]

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. If "" is passed for szSeedFile, it returns the support status for Intel DRNG (see Remarks).

VBA Wrapper Syntax

Public Function rngInitialize (szSeedFile As String) As Long
Public Function rngInitializeEx (Optional nOptions As Long = 0) As Long

.NET Equivalent

Rng.Initialize Method
Rng.InitializeEx Method

C++ (STL) Equivalent

static int dipki::Rng::Initialize (const std::string &seedFile)
static int dipki::Rng::InitializeEx (Opts opts=Opts::Default)
static Rng.initialize_ex(opts=0)

Python Equivalent

static Rng.initialize(seedfilename)
static Rng.initialize_ex(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.

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_UpdateSeedFile

[Contents] [Index]

RNG_MakeSeedFile

Creates a new seed file suitable for use with 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.

.NET Equivalent

Rng.MakeSeedFile Method

Python Equivalent

static Rng.make_seedfile(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_UpdateSeedFile

[Contents] [Index]

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
Rng.Octet Method

C++ (STL) Equivalent

static int dipki::Rng::Number (int lower, int upper)
static Rng.octet()

Python Equivalent

static Rng.number(lower, upper)
static Rng.octet()

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

[Contents] [Index]

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.

.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 for more information on the RNG and seeds.

Example

See Also

RNG_Bytes

[Contents] [Index]

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.

.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 for more information on the RNG and seeds.

Example

See Also

RNG_BytesWithPrompt

[Contents] [Index]

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.

.NET Equivalent

Rng.Test Method

Remarks

This function carries out, on demand, the health testing procedure from section 11.3 of [SP80090A] and the statistical tests for randomness from section 4.9.1 of the October 2001 version of FIPS-140-2 [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

[Contents] [Index]

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.

.NET Equivalent

Rng.TestDrbgvs Method

Python Equivalent

static Rng.test_drbgvs(returnedBitsLen, entropyInput, nonce, personalizationString, additionalInput1, entropyReseed, additionalInputReseed, additionalInput2)

Remarks

The test procedure, the input values and the expected output are described in the [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

[Contents] [Index]

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.

.NET Equivalent

Rng.UpdateSeedFile Method

C++ (STL) Equivalent

static int dipki::Rng::UpdateSeedFile (const std::string &seedFile)

Python Equivalent

static Rng.update_seedfile(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.

See Also

RNG_Initialize RNG_MakeSeedFile

[Contents] [Index]

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.

.NET Equivalent

Rsa.CheckKey Method (String)
Rsa.CheckKey Method (StringBuilder)

C++ (STL) Equivalent

static bool dipki::Rsa::KeyIsPrivate (const std::string &keyStr)

Python Equivalent

static Rsa.key_isprivate(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.

See Also

RSA_KeyBits RSA_KeyBytes RSA_KeyHashCode

[Contents] [Index]

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 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.

VBA Wrapper Syntax

Public Function rsaDecodeMsg (lpInput() As Byte, nOptions As Long) As Byte()

.NET Equivalent

Rsa.DecodeMsgForEncryption Method
Rsa.DecodeDigestForSignature Method
Rsa.DecodeMsgIso9796 Method

static Rsa.decode_msg_for_encryption(data, method=EME.PKCSV1_5)

Python Equivalent

static Rsa.decode_digest_for_signature(data, full_digestinfo=False)
static Rsa.decode_msg_for_encryption(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 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() function on the original message and then compare the result of that with the input block you have here. See Raw RSA Techniques. 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_RawPublic RSA_RawPrivate Raw RSA Techniques

[Contents] [Index]

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, 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.

VBA Wrapper Syntax

Public Function rsaDecrypt (lpInput() As Byte, szPrivateKeyFile As String, szPassword As String, nOptions As Long, Optional szParameters As String = "") As Byte()

.NET Equivalent

Rsa.Decrypt Method

C++ (STL) Equivalent

static bvec_t dipki::Rsa::Decrypt (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(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.

Example (VBA core function)

See RSA_Encrypt.

Example (VBA wrapper function)

See example for VBA wrapper rsaEncrypt in RSA_Encrypt.

See Also

RSA_Encrypt RSA_DecodeMsg RSA_RawPrivate

[Contents] [Index]

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 for more details.

Returns (VBA/C)

If successful, the return value is zero; otherwise it returns a negative error code.
CAUTION: This function assumes you know the required length of the output. It does not return the length.

VBA Wrapper Syntax

Public Function rsaEncodeMsg (nBlockLen As Long, lpInput() As Byte, nOptions As Long) As Byte()

.NET Equivalent

Rsa.EncodeMsgForEncryption Method
Rsa.EncodeMsgForSignature Method
Rsa.EncodeDigestForSignature Method
Rsa.EncodeMsgIso9796 Method

static Rsa.encode_msg_for_encryption(keybytes, message, method=EME.PKCSV1_5)

Python Equivalent

static Rsa.encode_msg_for_signature(keybytes, message, hashalg=HashAlg.SHA1, digest_only=False)
static Rsa.encode_msg_for_encryption(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() 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() 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 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.

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_RawPublic RSA_RawPrivate Raw RSA Techniques

[Contents] [Index]

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, 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.

VBA Wrapper Syntax

Public Function rsaEncrypt (lpInput() As Byte, szPublicKeyFile As String, Optional nOptions As Long = 0, Optional szParameters As String = "") As Byte()

.NET Equivalent

Rsa.Encrypt Method

C++ (STL) Equivalent

static bvec_t dipki::Rsa::Encrypt (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(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() 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.

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_EncodeMsg RSA_RawPublic

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function rsaFromXMLString (szXmlString As String, Optional nOptions As Long = 0) As String

.NET Equivalent

Rsa.FromXMLString Method (String)
Rsa.FromXMLString Method (String, Rsa.XmlOptions)
Rsa.FromXMLString Method (String, Boolean)

C++ (STL) Equivalent

static std::string dipki::Rsa::FromXMLString (const std::string &xmlstr, XmlOptions opts=XmlOptions::None)

Python Equivalent

static Rsa.from_xmlstring(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 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] or [XKMS2]. 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]. 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

[Contents] [Index]

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.

.NET Equivalent

Rsa.GetPrivateKeyFromPFX Method

C++ (STL) Equivalent

static int dipki::Rsa::GetPrivateKeyFromPFX (const std::string &outputFile, const std::string &pfxFile)

Python Equivalent

static Rsa.get_privatekey_from_pfx(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_ReadPrivateKeyFromPFX PFX_MakeFile

[Contents] [Index]

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).
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.

.NET Equivalent

Rsa.GetPublicKeyFromCert Method

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.

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_ReadPublicKeyFromCert". 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].

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_PublicKeyFromPrivate X509_GetCertFromP7Chain X509_GetCertFromPFX

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function rsaKeyBits (szKeyString As String) As Long

.NET Equivalent

Rsa.KeyBits Method (String)
Rsa.KeyBits Method (StringBuilder)

C++ (STL) Equivalent

static int dipki::Rsa::KeyBits (const std::string &keyStr)

Python Equivalent

static Rsa.key_bits(keystr)

Remarks

Example

See Also

RSA_KeyBytes

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function rsaKeyBytes (szKeyString As String) As Long

.NET Equivalent

Rsa.KeyBytes Method (String)
Rsa.KeyBytes Method (StringBuilder)

C++ (STL) Equivalent

static int dipki::Rsa::KeyBytes (const std::string &keyStr)

Python Equivalent

static Rsa.key_bytes(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_RawPublic RSA_RawPrivate

[Contents] [Index]

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 (String)
Rsa.KeyHashCode Method (StringBuilder)

C++ (STL) Equivalent

static uint32_t dipki::Rsa::KeyHashCode (const std::string &intKeyString)

Python Equivalent

static Rsa.key_hashcode(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 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.

See Also

RSA_KeyBits RSA_KeyBytes

[Contents] [Index]

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.

.NET Equivalent

Rsa.KeyMatch Method (String)
Rsa.KeyMatch Method (StringBuilder)

C++ (STL) Equivalent

static bool dipki::Rsa::KeyMatch (const std::string &priKeyStr, const std::string &pubKeyStr)

Python Equivalent

static Rsa.key_match(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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function rsaKeyValue (szKeyString As String, szFieldName As String, Optional nOptions As Long = 0) As String

.NET Equivalent

Rsa.KeyValue Method

C++ (STL) Equivalent

static std::string dipki::Rsa::KeyValue (const std::string &keyStr, const std::string &fieldName)

Python Equivalent

static Rsa.key_value(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 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] [Index]

RSA_MakeKeys

Generate an RSA key pair and save as two key files. [Superseded by 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
(there are more options - see security options for encrypted private keys)
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.

VBA Wrapper Syntax

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

.NET Equivalent

Rsa.MakeKeys Method (String, String, Int32, Rsa.PublicExponent, Int32, String, Rsa.PbeOptions, Boolean, Byte[])
Rsa.MakeKeys Method (String, String, Int32, Rsa.PublicExponent, Int32, String, CipherAlgorithm, HashAlgorithm, Rsa.Format, Boolean)

C++ (STL) Equivalent

static int dipki::Rsa::MakeKeys (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 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() and RSA_SaveEncPrivateKey().

Generating RSA key pairs can take some time. On a 1GHz P3 test machine, the following times were typical:

Key sizeTime
512< 1 second
10245 seconds
20481 minute
40966 minutes
81921 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_ReadPublicKey RSA_SaveEncPrivateKey RSA_SavePublicKey

[Contents] [Index]

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 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)
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.

.NET Equivalent

Rsa.MakeKeys Method

Python Equivalent

static Rsa.make_keys(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] [Index]

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.

VBA Wrapper Syntax

Public Function rsaPublicKeyFromPrivate (szKeyString As String, Optional nOptions As Long = 0) As String

.NET Equivalent

Rsa.PublicKeyFromPrivate Method

C++ (STL) Equivalent

static std::string dipki::Rsa::PublicKeyFromPrivate (const std::string &keyStr)

Python Equivalent

static Rsa.publickey_from_private(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 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_ReadEncPrivateKey

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function rsaRawPrivate (lpData() As Byte, szPrivateKey As String, Optional nOptions As Long = 0) As Byte()

.NET Equivalent

Rsa.RawPrivate Method (Byte[], String)
Rsa.RawPrivate Method (Byte[], String, Int32)

C++ (STL) Equivalent

static bvec_t dipki::Rsa::RawPrivate (const bvec_t &data, const std::string &keyStr)

Python Equivalent

static Rsa.raw_private(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]. 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_EncodeMsg Raw RSA Techniques

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function rsaRawPublic (lpData() As Byte, szPublicKey As String, Optional nOptions As Long = 0) As Byte()

.NET Equivalent

Rsa.RawPublic Method (Byte[], String)
Rsa.RawPublic Method (Byte[], String, Int32)

C++ (STL) Equivalent

static bvec_t dipki::Rsa::RawPublic (const bvec_t &data, const std::string &keyStr)

Python Equivalent

static Rsa.raw_public(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]:

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_EncodeMsg Raw RSA Techniques

[Contents] [Index]

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 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.

VBA Wrapper Syntax

Public Function rsaReadAnyPrivateKey (szKeyFileOrString As String, Optional szPassword As String = "", Optional nOptions As Long = 0) As String
Public Function rsaReadPrivateKey (szKeyFileOrString As String, Optional szPassword As String = "", Optional nOptions As Long = 0) As String

.NET Equivalent

Rsa.ReadPrivateKey Method

C++ (STL) Equivalent

static std::string dipki::Rsa::ReadPrivateKey (const std::string &keyFileOrString, const std::string &password="")

Python Equivalent

static Rsa.read_private_key(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 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:

This supersedes the following functions:

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

[Contents] [Index]

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 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.

VBA Wrapper Syntax

Public Function rsaReadAnyPublicKey (szKeyFileOrString As String, Optional nOptions As Long = 0) As String

.NET Equivalent

Rsa.ReadPublicKey Method

C++ (STL) Equivalent

static std::string dipki::Rsa::ReadPublicKey (const std::string &keyFileOrString)

Python Equivalent

static Rsa.read_public_key(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 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:

To read in a public key from a PFX/p12 file, use RSA_ReadAnyPrivateKey then RSA_PublicKeyFromPrivate.

This supersedes the following functions:

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

[Contents] [Index]

RSA_ReadEncPrivateKey

Reads from an encrypted PKCS#8 private key info file into an "internal" private key string. [Superseded by 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).
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.

.NET Equivalent

Rsa.ReadEncPrivateKey Method

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_ReadPrivateKeyInfo RSA_SavePrivateKeyInfo RSA_GetPrivateKeyFromPFX

[Contents] [Index]

RSA_ReadPrivateKeyFromPFX

Reads a private key directly from an encrypted PFX/PKCS-12 file into an "internal" private key string. [Superseded by 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)
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.

.NET Equivalent

Rsa.ReadPrivateKeyFromPFX Method

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 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().

If you just want to extract the encrypted private key and save directly as a pkcs-8 file, then use the 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_ReadEncPrivateKey RSA_PublicKeyFromPrivate

[Contents] [Index]

RSA_ReadPrivateKeyInfo

Reads from an (unencrypted) PKCS-8 private key info file into an "internal" private key string. [Superseded by 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).
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.

.NET Equivalent

Rsa.ReadPrivateKeyInfo Method

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] 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_KeyHashCode

[Contents] [Index]

RSA_ReadPublicKey

Reads from an RSA public key file into an "internal" public key string. [Superseded by 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).
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.

VBA Wrapper Syntax

Public Function rsaReadPublicKey (szKeyFileOrString As String, Optional nOptions As Long = 0) As String

.NET Equivalent

Rsa.ReadPublicKey Method

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. 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_SavePublicKey RSA_GetPublicKeyFromCert

[Contents] [Index]

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 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)
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.

VBA Wrapper Syntax

Public Function 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

C++ (STL) Equivalent

static int dipki::Rsa::SaveEncKey (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(outputfile, intkeystr, password, pbescheme=0, params='', fileformat=0)

Remarks

[New in v20.3]

Example

See Also

[Contents] [Index]

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)
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.

.NET Equivalent

Rsa.SaveEncPrivateKey Method
Rsa.SaveEncPrivateKey Method

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] and saves in encrypted format with the password "password". It then checks that the two keys match by using the 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

[Contents] [Index]

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.

.NET Equivalent

Rsa.SavePrivateKeyInfo Method

Python Equivalent

static Rsa.save_key(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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function rsaSaveKey (szOutputFile As String, szKeyStr As String, Optional nOptions As Long = 0) As Long

.NET Equivalent

Rsa.SavePublicKey Method

C++ (STL) Equivalent

static int dipki::Rsa::SaveKey (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.

See Also

RSA_ReadPublicKey RSA_GetPublicKeyFromCert

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function rsaToXMLString (szKeyString As String, Optional nOptions As Long = 0) As String

.NET Equivalent

Rsa.ToXMLString Method (String, Rsa.XmlOptions)

C++ (STL) Equivalent

static std::string dipki::Rsa::ToXMLString (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 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].

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-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] and [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() 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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function rsaToXMLStringEx (szKeyString As String, szPrefix As String, Optional nOptions As Long = 0) As String

.NET Equivalent

Rsa.ToXMLString Method (String, String, Rsa.XmlOptions)

Python Equivalent

static Rsa.to_xmlstring(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 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.

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

[Contents] [Index]

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, 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.
nOptions
[in] Zero (0) for defaults.
Add the bitflag:
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" encoding of [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] 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)
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.

VBA Wrapper Syntax

Public Function 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
Sig.SignDigest Method

C++ (STL) Equivalent

static std::string dipki::Sig::SignData (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(digest, keyfile, password, alg, opts=Opts.DEFAULT, encoding=Encoding.DEFAULT)

Python Equivalent

static Sig.sign_data(data, keyfile, password, alg, opts=Opts.DEFAULT, encoding=Encoding.DEFAULT)
static Sig.sign_digest(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 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 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]

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

[Contents] [Index]

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, 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.
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" encoding of [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] 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)
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.

VBA Wrapper Syntax

Public Function 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

C++ (STL) Equivalent

static std::string dipki::Sig::SignFile (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(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 when allocating memory.

This function is identical to 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.

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

[Contents] [Index]

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 or base64 representation).
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.
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.

VBA Wrapper Syntax

Public Function 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
Sig.VerifyDigest Method

C++ (STL) Equivalent

static bool dipki::Sig::VerifyData (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(sig, digest, certorkey, alg, verifyopts=VerifyOpts.DEFAULT)

Python Equivalent

static Sig.data_is_verified(sig, data, certorkey, alg, verifyopts=VerifyOpts.DEFAULT)
static Sig.digest_is_verified(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). 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

[Contents] [Index]

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 or base64 representation).
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.
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.

.NET Equivalent

Sig.VerifyFile Method

C++ (STL) Equivalent

static bool dipki::Sig::VerifyFile (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(sig, datafile, certorkey, alg, verifyopts=VerifyOpts.DEFAULT)

Remarks

This function is identical to 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.

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

[Contents] [Index]

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.

.NET Equivalent

Smime.Extract Method

C++ (STL) Equivalent

static int dipki::Smime::Extract (const std::string &outputFile, const std::string &inputFile, Encoding encoding=Encoding::Default)

Python Equivalent

static Smime.extract(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. The output should be a binary file identical to the original binary CMS file.

See Also

SMIME_Wrap

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function smimeQuery (szFileIn As String, szQuery As String, Optional nOptions As Long = 0) As String

.NET Equivalent

Smime.Query Method

C++ (STL) Equivalent

static std::string dipki::Smime::Query (const std::string &inputFile, const std::string &query)

Python Equivalent

static Smime.query(filename, query)

Remarks

Valid queries are (case-insensitive):

Query StringReturns
content-typeValue of Content-Type, e.g. "application/pkcs7-mime"
smime-typeValue of smime-type parameter of Content-Type, e.g. "enveloped-data"
encodingValue of Content-Transfer-Encoding, e.g. "base64"
nameValue of name parameter of Content-Type, e.g. "smime.p7m"
filenameValue 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 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

[Contents] [Index]

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.

.NET Equivalent

Smime.Wrap Method

C++ (STL) Equivalent

static int dipki::Smime::Wrap (const std::string &outputFile, const std::string &inputFile, Encoding encoding=Encoding::Default, AdvOpts advopts=AdvOpts::Default)

Python Equivalent

static Smime.wrap(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]. 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. 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

[Contents] [Index]

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.

.NET Equivalent

Tdea.Encrypt Method (String, String, Mode, String, EncodingBase)
Tdea.Decrypt Method (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 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_HexMode

[Contents] [Index]

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.

.NET Equivalent

Tdea.Encrypt Method (Byte[], Byte[], Mode, Byte[])
Tdea.Decrypt Method (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_B64Mode TDEA_File

[Contents] [Index]

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.

.NET Equivalent

Tdea.FileEncrypt Method (String, String, Byte[], Mode, Byte[])
Tdea.FileDecrypt Method (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], which is the same as the padding method in [PKCS7] section 10.3 and [PKCS5] section 6.1.1 and [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

[Contents] [Index]

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.

.NET Equivalent

Tdea.Encrypt Method (String, String, Mode, String)
Tdea.Decrypt Method (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].

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_B64Mode

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function wipeBytes (ByRef lpToWipe() As Byte) As Byte()
Public Function wipeString (ByRef szToWipe As String) As String

.NET Equivalent

Wipe.Data Method
Wipe.String Method

C++ (STL) Equivalent

static bool dipki::Wipe::Data (bvec_t &data)
static bool dipki::Wipe::String (std::string &s)

Python Equivalent

static Wipe.data(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] [Index]

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.

.NET Equivalent

Wipe.File Method

C++ (STL) Equivalent

static bool dipki::Wipe::File (const std::string fileName, Opts opts=Opts::Dod7Pass)

Python Equivalent

static Wipe.file(filename, opts=Options.DEFAULT)

Remarks

Wipes a file using the 7-pass DOD Standard according to [NISPOM] before deleting.

Example

nRet = WIPE_File("ToDelete.txt", 0)

See Also

[Contents] [Index]

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).
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.

.NET Equivalent

X509.CertExpiresOn Method

Remarks

The time format is in accordance with ISO 8601 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_CertIsValidNow X509_QueryCert

[Contents] [Index]

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).
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.

.NET Equivalent

X509.CertIssuedOn Method

Remarks

The time format is in accordance with ISO 8601 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.

See Also

X509_CertExpiresOn X509_CertIsValidNow X509_QueryCert

[Contents] [Index]

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).
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 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.

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

Remarks

See the remarks for X509_CertSubjectName().

Example

See X509_CertSubjectName.

See Also

X509_CertIssuerName X509_HashIssuerAndSN X509_QueryCert

[Contents] [Index]

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).
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.

.NET Equivalent

X509.CertIsValidNow Method

C++ (STL) Equivalent

static bool dipki::X509::CertIsValidNow (const std::string &certFile)

Python Equivalent

static X509.cert_is_valid_now(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_ValidatePath X509_CertThumb

[Contents] [Index]

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 containing the key.
szDistName
[in] Distinguished name string. See Specifying Distinguished Names 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. [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] for an ECDSA signature.

Returns (VBA/C)

If successful, the return value is zero; otherwise it returns a nonzero error code.

.NET Equivalent

X509.CertRequest Method

C++ (STL) Equivalent

static int dipki::X509::CertRequest (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(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]. 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

[Contents] [Index]

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).
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.

.NET Equivalent

X509.CertSerialNumber Method

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_CertThumb

[Contents] [Index]

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).
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 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.

.NET Equivalent

X509.CertSubjectName Method

Remarks

The distinguished name will be returned in a string expressed in the same format described in Distinguished Names, 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, 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]. See LDAP string representation 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_HashIssuerAndSN X509_QueryCert

[Contents] [Index]

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).
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.

VBA Wrapper Syntax

Public Function x509CertThumb (szCertFile As String, Optional nOptions As Long = 0) As String

.NET Equivalent

X509.CertThumb Method

C++ (STL) Equivalent

static std::string dipki::X509::CertThumb (const std::string &certFile, HashAlg hashAlg=HashAlg::Sha1)

Python Equivalent

static X509.cert_thumb(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 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_VerifyCert

[Contents] [Index]

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).
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).
szDate
[in] (optional) with date in ISO date format (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.

.NET Equivalent

X509.CheckCertInCRL Method

Python Equivalent

static X509.cert_is_revoked(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() 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_VerifyCert X509_CertIsValidNow X509_ValidatePath

[Contents] [Index]

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.
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.

.NET Equivalent

X509.GetCertCountInP7Chain Method

C++ (STL) Equivalent

static int dipki::X509::GetCertCountInP7Chain (const std::string &inputFile)

Python Equivalent

static X509.get_cert_count_from_p7(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_ReadCertStringFromP7Chain CMS_QuerySigData

[Contents] [Index]

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.
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.

.NET Equivalent

X509.GetCertFromP7Chain Method

C++ (STL) Equivalent

static bool dipki::X509::GetCertFromP7Chain (const std::string &outputFile, const std::string &inputFile, int index)

Python Equivalent

static X509.get_cert_from_p7(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. 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_GetCertCountInP7Chain CMS_QuerySigData

[Contents] [Index]

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.

.NET Equivalent

X509.GetCertFromPFX Method
X509.GetP7ChainFromPFX Method

C++ (STL) Equivalent

static bool dipki::X509::GetCertFromPFX (const std::string &outputFile, const std::string &inputFile, const std::string &password)
static X509.get_p7chain_from_pfx(outfile, pfxfile, password)

Python Equivalent

static X509.get_cert_from_pfx(outfile, pfxfile, password)
static X509.get_p7chain_from_pfx(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 PFX_VerifySig

[Contents] [Index]

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).
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.

VBA Wrapper Syntax

Public Function x509HashIssuerAndSN (szCertFile As String, Optional nOptions As Long = 0) As String

.NET Equivalent

X509.HashIssuerAndSN Method

C++ (STL) Equivalent

static std::string dipki::X509::HashIssuerAndSN (const std::string &certFile, HashAlg hashAlg=HashAlg::Sha1)

Python Equivalent

static X509.cert_hashissuersn(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 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_CertThumb

[Contents] [Index]

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).

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.

.NET Equivalent

X509.KeyUsageFlags Method

Python Equivalent

static X509.key_usage_flags(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

[Contents] [Index]

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 or as a PEM string).
szSubjectPubKeyFile
[in] Name of subject's public key file or a PEM string 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 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 for more details.
szExtensions
[in] Extensions: a list of attribute-value pairs separated by semicolons (;). See X.509 Extensions Parameter. Specify "" or NULL to ignore.
nKeyUsageFlags
[in] Bit flags to set Key Usage extension:
OptionTo set
PKI_X509_KEYUSAGE_DIGITALSIGNATUREdigitalSignature
PKI_X509_KEYUSAGE_NONREPUDIATIONnonRepudiation
PKI_X509_KEYUSAGE_KEYENCIPHERMENTkeyEncipherment
PKI_X509_KEYUSAGE_DATAENCIPHERMENTdataEncipherment
PKI_X509_KEYUSAGE_KEYAGREEMENTkeyAgreement
PKI_X509_KEYUSAGE_KEYCERTSIGNkeyCertSign
PKI_X509_KEYUSAGE_CRLSIGNcRLSign
PKI_X509_KEYUSAGE_ENCIPHERONLYencipherOnly
PKI_X509_KEYUSAGE_DECIPHERONLYdecipherOnly
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] for an ECDSA signature.

Returns (VBA/C)

If successful, the return value is zero; otherwise it returns a nonzero error code.

.NET Equivalent

X509.MakeCert Method

C++ (STL) Equivalent

static int dipki::X509::MakeCert (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(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 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).

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).

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). 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, and mark an arbitrary extension 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].

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

[Contents] [Index]

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 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 for more details.
szExtensions
[in] Extensions: optional list of attribute-value pairs separated by semicolons (;). See X.509 Extensions Parameter. Specify "" or NULL to ignore.
nKeyUsageFlags
[in] Flags to set Key Usage extensions:
PKI_X509_KEYUSAGE_DIGITALSIGNATUREto set digitalSignature
PKI_X509_KEYUSAGE_NONREPUDIATIONto set nonRepudiation
PKI_X509_KEYUSAGE_KEYENCIPHERMENTto set keyEncipherment
PKI_X509_KEYUSAGE_DATAENCIPHERMENTto set dataEncipherment
PKI_X509_KEYUSAGE_KEYAGREEMENTto set keyAgreement
PKI_X509_KEYUSAGE_KEYCERTSIGNto set keyCertSign
PKI_X509_KEYUSAGE_CRLSIGNto set cRLSign
PKI_X509_KEYUSAGE_ENCIPHERONLYto set encipherOnly
PKI_X509_KEYUSAGE_DECIPHERONLYto 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] for an ECDSA signature.

Returns (VBA/C)

If successful, the return value is zero; otherwise it returns a nonzero error code.

.NET Equivalent

X509.MakeCertSelf Method

C++ (STL) Equivalent

static int dipki::X509::MakeCertSelf (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(newcertfile, prikeyfile, password, certnum, yearsvalid, distname, extns="", keyusage=0, sigalg=0, opts=0)

Remarks

See the remarks for 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

[Contents] [Index]

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).
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:
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] for an ECDSA signature.

Returns (VBA/C)

If successful, the return value is zero; otherwise it returns a nonzero error code.

.NET Equivalent

X509.MakeCRL Method

C++ (STL) Equivalent

static int dipki::X509::MakeCRL (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(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 (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 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

[Contents] [Index]

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).
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 (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.

VBA Wrapper Syntax

Public Function x509QueryCert (szCertFile As String, szQuery As String, Optional nOptions As Long = 0) As String

.NET Equivalent

X509.QueryCert Method

C++ (STL) Equivalent

static std::string dipki::X509::QueryCert (const std::string &certFile, const std::string &query, OutputOpts outOpts=OutputOpts::Default_OutputOpt)

Python Equivalent

static X509.query_cert(filename, query, opts=0)

Remarks

Valid queries are (case-insenitive):

Query StringReturnsData Type
versionX.509 version number, e.g. 1 or 3. Number
serialNumberSerial number in hex-encoded formatString
signatureAlgorithmSignature algorithm used, e.g. "sha1WithRSAEncryption". String
sigAlgIdID of signature algorithm used, see PKI_SIG_* valuesNumber
signatureValueSignature value in hex-encoded formatString
notBeforeDate on which the certificate validity period begins in format yyyy-mm-ddThh:nn:ssZString
notAfterDate on which the certificate validity period ends in format yyyy-mm-ddThh:nn:ssZString
issuerNameDistinguished name (DN) of entity who has signed and issued the certificateString
subjectNameDistinguished name (DN) of the subjectString
subjectPublicKeyAlgorithmAlgorithm used in subject's public key, e.g. "dsa" or "rsaEncryption". String
subjectKeyIdentifierThe subject key identifier extension, if present, in hex-encoded formatString
authorityKeyIdentifierThe authority key identifier extension, if present, in hex-encoded formatString
rfc822NameFirst internet mail address found contained in a subjectAltName extension, if presentString
isCAReturns 1 if the subject type is a CA, otherwise returns 0. Number
keyUsageStringkeyUsage flags in text format, e.g. "digitalSignature,nonRepudiation"String
extKeyUsageStringextKeyUsage purposes in text format, e.g. "codeSigning,timeStamping"String
cRLDistributionPointsURIFirst URI found in cRLDistributionPoints, if anyString
authorityInfoAccessURIFirst URI found in authorityInfoAccess, if anyString
subjectAltNameSubject alternative name extension, if present. [New in v10.0]String
hashAlgorithmHash algorithm used in signature, e.g. "sha256". [New in v12.0]String
pssParamsParameters used for RSA-PSS (if applicable). [New in v12.0]String

Some of these queries duplicate or complement existing functions:

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 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_CertSubjectName

[Contents] [Index]

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.
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.

VBA Wrapper Syntax

Public Function x509ReadCertStringFromP7Chain (szP7cFile As String, nIndex As Long, Optional nOptions As Long = 0) As String

.NET Equivalent

X509.ReadCertStringFromP7Chain Method

C++ (STL) Equivalent

static std::string dipki::X509::ReadCertStringFromP7Chain (const std::string &inputFile, int index)

Python Equivalent

static X509.read_cert_string_from_p7chain(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 when allocating memory.

The output is a base64 string representation 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. 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. 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_GetCertCountInP7Chain CMS_QuerySigData

[Contents] [Index]

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.
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.

VBA Wrapper Syntax

Public Function x509ReadCertStringFromPFX (szPfxFile As String, szPassword As String, Optional nOptions As Long = 0) As String

.NET Equivalent

X509.ReadCertStringFromPFX Method

C++ (STL) Equivalent

static std::string dipki::X509::ReadCertStringFromPFX (const std::string &inputFile, const std::string &password)

Python Equivalent

static X509.read_cert_string_from_pfx(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 when allocating memory.

The default behaviour is to extract one certificate from the PFX file and output as a base64 string representation 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

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function x509ReadStringFromFile (szCertFile As String, Optional nOptions As Long = 0) As String

.NET Equivalent

X509.ReadStringFromFile Method

C++ (STL) Equivalent

static std::string dipki::X509::ReadStringFromFile (const std::string &certFile)

Python Equivalent

static X509.read_string_from_file(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 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 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

[Contents] [Index]

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.

.NET Equivalent

X509.SaveFileFromString Method

C++ (STL) Equivalent

static int dipki::X509::SaveFileFromString (const std::string &newCertFile, const std::string &certString, bool inPEMFormat=false)

Python Equivalent

static X509.save_file_from_string(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(). 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.

See Also

X509_ReadStringFromFile

[Contents] [Index]

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).
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.
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.

.NET Equivalent

X509.TextDump Method

Python Equivalent

static X509.text_dump(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 or as a PEM string. 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 ASN1_TextDump

[Contents] [Index]

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 or PEM string 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.
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.

VBA Wrapper Syntax

Public Function x509TextDumpToString (szCertFile As String, Optional nOptions As Long = 0) As String

.NET Equivalent

X509.TextDumpToString Method

C++ (STL) Equivalent

static std::string dipki::X509::TextDumpToString (const std::string &certFile, OutputOpts outOpts=OutputOpts::Default_OutputOpt)

Python Equivalent

static X509.text_dump_tostring(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 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 or as a PEM string.

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 ASN1_TextDump

[Contents] [Index]

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).
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.

.NET Equivalent

X509.ValidatePath Method (String)

Python Equivalent

static X509.cert_path_is_valid(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() 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().

[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_CertIsValidNow X509_CheckCertInCRL

[Contents] [Index]

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).
szIssuerCert
[in] Name of the issuer's certificate file (or a PEM string). 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.

.NET Equivalent

X509.VerifyCert Method

Python Equivalent

static X509.cert_is_verified(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()). Nor does it check that the certficate has been revoked (to do that use X509_CheckCertInCRL()). Only certificates signed with supported signature algorithms can be checked: see Supported Algorithms. The certificate file may be in binary BER/DER format or base64 PEM file format, or may be passed in base64 representation or as a PEM string.

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_ValidatePath X509_CheckCertInCRL

[Contents] [Index]

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.

VBA Wrapper Syntax

Public Function xofBytes (nBytes As Long, lpMessage() As Byte, nOptions As Long) As Byte()

.NET Equivalent

Xof.Bytes Method

C++ (STL) Equivalent

static bvec_t dipki::Xof::Bytes (int numBytes, const bvec_t &message, XofAlg xofalg)

Python Equivalent

static Xof.bytes(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]. 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].

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

[Contents] [Index]

VBA Wrapper Functions

The wrapper functions for VBA/VB6 programmers are now all in basCrPKI.bas. See Notes on VBA wrapper functions.

VBA Wrapper Function List

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.

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"

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.

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.

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.

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.

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.

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.

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.

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.

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).

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).

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.

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)

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.
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

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.
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

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.

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.

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.

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.

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.

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.

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.

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().

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.

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().

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.

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.

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.

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

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.

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.

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.

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).

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.

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.

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

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.

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

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

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

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.

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

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

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.

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.

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.

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

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

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

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.

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

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

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.

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.

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.

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.

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.

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)

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.

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.

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.

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.

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.

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}.

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.

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)

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.

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.

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.

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.

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.

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

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.

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.

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.

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, eccSaveEncKey, eccPublicKeyFromPrivate, eccDHSharedSecret and 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).

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.

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.

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"

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"

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.

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.

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.

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.

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.

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.

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.

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.

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.

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

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

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.

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).

Remarks

Not all functions set this value.

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.

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).

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.

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".

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

pkiPlatform

Get platform the core DLL was compiled for.

Syntax

[VBA]
Public Function pkiPlatform() As String

Return Value

String: "Win32" or "X64".

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.

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.

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.

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.

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

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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)

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.

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).

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).

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.

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.

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.

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.

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}.

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.

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.

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>.

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.

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.

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.

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

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()

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)

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.

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.

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

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.

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.

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.

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.

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] [Index]

C++ (STL) Functions

See Using with C++ (STL).

[Contents] [Index]

.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. For more guidance on programming, see Using with .NET: C# and VB.NET.

[Contents] [Index]

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.

FunctionEquivalent .NET MethodVBA Wrapper
ASN1_TextDump Asn1.TextDump Method
 
ASN1_TextDumpToString Asn1.TextDumpToString Method
asn1TextDumpToString
ASN1_Type Asn1.Type Method
asn1Type
CIPHER_Bytes - @deprecated Cipher.Encrypt Method (Byte[], Byte[], Byte[], CipherAlgorithm, Mode)
Cipher.Decrypt Method (Byte[], Byte[], Byte[], CipherAlgorithm, Mode)
 
CIPHER_DecryptAEAD Cipher.DecryptAEAD Method (Byte[], Byte[], Byte[], AeadAlgorithm)
Cipher.DecryptAEAD Method (Byte[], Byte[], Byte[], Byte[], AeadAlgorithm, Cipher.Opts)
cipherDecryptAEAD
CIPHER_DecryptBytes Cipher.Decrypt Method (Byte[], Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)
cipherDecryptBytes
CIPHER_DecryptHex Cipher.Decrypt Method (String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts)
cipherDecryptHex
CIPHER_EncryptAEAD Cipher.EncryptAEAD Method (Byte[], Byte[], Byte[], AeadAlgorithm)
Cipher.EncryptAEAD Method (Byte[], Byte[], Byte[], Byte[], AeadAlgorithm, Cipher.Opts)
cipherEncryptAEAD
CIPHER_EncryptBytes Cipher.Encrypt Method (Byte[], Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)
cipherEncryptBytes
CIPHER_EncryptHex Cipher.Encrypt Method (String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts)
cipherEncryptHex
CIPHER_File - @deprecated Cipher.FileEncrypt Method
Cipher.FileDecrypt Method
 
CIPHER_FileDecrypt Cipher.FileDecrypt Method (String, String, Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)
Cipher.FileDecrypt Method (String, String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts)
cipherFileDecrypt
CIPHER_FileEncrypt Cipher.FileEncrypt Method (String, String, Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)
Cipher.FileEncrypt Method (String, String, String, String, CipherAlgorithm, Mode, Padding, Cipher.Opts)
cipherFileEncrypt
CIPHER_Hex Cipher.Encrypt Method (String, String, String, CipherAlgorithm, Mode)
Cipher.Decrypt Method (String, String, String, CipherAlgorithm, Mode)
 
CIPHER_KeyUnwrap Cipher.KeyUnwrap Method
cipherKeyUnwrap
CIPHER_KeyWrap Cipher.KeyWrap Method
cipherKeyWrap
CMS_GetSigDataDigest Cms.GetSigDataDigest Method
cmsGetSigDataDigest
CMS_MakeComprData Cms.MakeComprData Method
 
CMS_MakeDetachedSig Cms.MakeDetachedSig Method
 
CMS_MakeEnvData Cms.MakeEnvData Method ( String, String, String, CipherAlgorithm, Cms.EnvDataOptions )
Cms.MakeEnvData Method ( String, String, String, CipherAlgorithm, Cms.KeyEncrAlgorithm, HashAlgorithm, Cms.EnvDataOptions, KdfAlg, KeyWrapAlg, String, Int32, Cms.ContentEncrAlg)
cmsMakeEnvData
CMS_MakeEnvDataFromBytes Cms.MakeEnvDataFromBytes Method
cmsMakeEnvDataFromBytes
CMS_MakeEnvDataFromString Cms.MakeEnvDataFromString Method (String, String, String, CipherAlgorithm, Cms.EnvDataOptions)
Cms.MakeEnvDataFromString Method (String, String, String, CipherAlgorithm, Cms.KeyEncrAlgorithm, HashAlgorithm, Cms.EnvDataOptions, KdfAlg, KeyWrapAlg, String, Int32, Cms.ContentEncrAlg)
cmsMakeEnvDataFromString
CMS_MakeSigData Cms.MakeSigData Method ( String, String, String, String, Cms.SigAlg, Cms.SigDataOptions)
Cms.MakeSigData Method ( String, String, String, String, HashAlgorithm, Cms.SigDataOptions)
 
CMS_MakeSigDataFromBytes Cms.MakeSigDataFromBytes Method
cmsMakeSigDataFromBytes
CMS_MakeSigDataFromSigValue Cms.MakeSigDataFromSigValue Method
Cms.MakeSigDataFromPseudo Method
cmsMakeSigDataFromSigValue
CMS_MakeSigDataFromString Cms.MakeSigDataFromString Method (String, String, String, String, Cms.SigAlg, Cms.SigDataOptions)
Cms.MakeSigDataFromString Method (String, String, String, String, HashAlgorithm, Cms.SigDataOptions)
 
CMS_QueryEnvData Cms.QueryEnvData Method
cmsQueryEnvData
CMS_QuerySigData Cms.QuerySigData Method
cmsQuerySigData
CMS_ReadComprData Cms.ReadComprData Method
 
CMS_ReadEnvData Cms.ReadEnvDataToFile Method
 
CMS_ReadEnvDataToBytes Cms.ReadEnvDataToBytes Method
cmsReadEnvDataToBytes
CMS_ReadEnvDataToString Cms.ReadEnvDataToString Method
cmsReadEnvDataToString
CMS_ReadSigData Cms.ReadSigDataToFile Method
 
CMS_ReadSigDataToBytes Cms.ReadSigDataToBytes Method
cmsReadSigDataToBytes
CMS_ReadSigDataToString Cms.ReadSigDataToString Method
cmsReadSigDataToString
CMS_VerifySigData Cms.VerifySigData Method
cmsVerifySigData
CNV_B64Filter Cnv.Base64Filter Method
cnvB64Filter
CNV_B64StrFromBytes Cnv.ToBase64 Method (Byte[])
Cnv.ToBase64 Method (String)
cnvToBase64
CNV_Base58FromBytes Cnv.ToBase58 Method
cnvBase58FromBytes
CNV_Base58ToBytes Cnv.FromBase58 Method
cnvBase58ToBytes
CNV_ByteEncoding Cnv.ByteEncoding Method
cnvByteEncoding
CNV_BytesFromB64Str Cnv.FromBase64 Method
cnvFromBase64
CNV_BytesFromHexStr Cnv.FromHex Method
cnvFromHex
CNV_CheckUTF8 - @deprecated Not applicable in .NET  
CNV_CheckUTF8Bytes Cnv.CheckUTF8 Method (Byte[])
cnvCheckUTF8Bytes
CNV_CheckUTF8File Cnv.CheckUTF8File Method
 
CNV_HexFilter Cnv.HexFilter Method
cnvHexFilter
CNV_HexStrFromBytes Cnv.ToHex Method
cnvToHex
CNV_Latin1FromUTF8 - @deprecated Not applicable in .NET  
CNV_Latin1FromUTF8Bytes Use System.Text.Encoding.UTF8.GetString(bytes).
cnvLatin1FromUTF8Bytes
CNV_NumFromBytes Cnv.NumFromBytes Method
cnvNumFromBytes
CNV_NumToBytes Cnv.NumToBytes Method
cnvNumToBytes
CNV_ReverseBytes Cnv.ReverseBytes Method
cnvReverseBytes
CNV_ShortPathName Cnv.ShortPathName Method
 
CNV_UTF8BytesFromLatin1 Use System.Text.Encoding.UTF8.GetBytes(Str).
cnvUTF8BytesFromLatin1
CNV_UTF8FromLatin1 - @deprecated Not applicable in .NET  
COMPR_Compress Compr.Compress Method
comprCompress
COMPR_Uncompress Compr.Uncompress Method
comprUncompress
ECC_DHSharedSecret Ecc.DHSharedSecret Method
eccDHSharedSecret
ECC_KeyHashCode Ecc.KeyHashCode Method
eccKeyHashCode
ECC_MakeKeys Ecc.MakeKeys Method
eccMakeKeys
ECC_PublicKeyFromPrivate Ecc.PublicKeyFromPrivate Method
eccPublicKeyFromPrivate
ECC_QueryKey Ecc.QueryKey Method
eccQueryKey
ECC_ReadKeyByCurve Ecc.ReadKeyByCurve Method
eccReadKeyByCurve
ECC_ReadPrivateKey Ecc.ReadPrivateKey Method
eccReadPrivateKey
ECC_ReadPublicKey Ecc.ReadPublicKey Method
eccReadPublicKey
ECC_SaveEncKey Ecc.SaveEncKey Method
eccSaveEncKey
ECC_SaveKey Ecc.SaveKey Method
eccSaveKey
HASH_Bytes Hash.BytesFromBytes Method
Hash.Double Method
hashBytes
HASH_File Hash.BytesFromFile Method
hashFile
HASH_HexFromBytes Hash.HexFromBytes Method
Hash.HexFromString Method
hashHexFromBytes
HASH_HexFromFile Hash.HexFromFile Method
Hash.HexFromTextFile Method
hashHexFromFile
HASH_HexFromHex Hash.HexFromHex Method
hashHexFromHex
HASH_Length Hash.Length Method
hashLength
HMAC_Bytes Hmac.BytesFromBytes Method
hmacBytes
HMAC_HexFromBytes Hmac.HexFromBytes Method
hmacHexFromBytes
HMAC_HexFromHex Hmac.HexFromHex Method
hmacHexFromHex
KDF_Bytes Kdf.Bytes Method
kdfBytes
HPKE_DerivePrivateKey Hpke.DerivePrivateKey Method
hpkeDerivePrivateKey
HPKE_LabeledExpand Hpke.LabeledExpand Method
hpkeLabeledExpand
HPKE_LabeledExtract Hpke.LabeledExtract Method
hpkeLabeledExtract
KDF_ForCms Kdf.ForCms Method
kdfForCms
OCSP_MakeRequest Ocsp.MakeRequest Method
ocspMakeRequest
OCSP_ReadResponse Ocsp.ReadResponse Method
ocspReadResponse
PAD_BytesBlock Cipher.Pad Method
padBytesBlock
PAD_HexBlock Cipher.Pad Method (String, CipherAlgorithm, Padding)
padHexBlock
PAD_UnpadBytes Cipher.Unpad Method (Byte[], CipherAlgorithm, Padding)
padUnpadBytes
PAD_UnpadHex Cipher.Pad Method (String, CipherAlgorithm, Padding)
padUnpadHex
PBE_Kdf2 Pbe.Kdf2 Method (Int32, Byte[], Byte[], Int32, HashAlgorithm)
pbeKdf2
PBE_Kdf2Hex Pbe.Kdf2 Method (Int32, String, String, Int32, HashAlgorithm)
pbeKdf2Hex
PBE_Scrypt Pbe.Scrypt Method
pbeScrypt
PBE_ScryptHex Pbe.Scrypt Method
pbeScryptHex
PEM_FileFromBinFile
PEM_FileFromBinFileEx
Pem.FileFromBinFile Method Pem.FileFromBinFile Method
 
PEM_FileToBinFile Pem.FileToBinFile Method
 
PFX_MakeFile Pfx.MakeFile Method
pfxMakeFile
PFX_VerifySig Pfx.SignatureIsValid Method
 
PKI_CompileTime General.CompileTime Method
pkiCompileTime
PKI_ErrorCode General.ErrorCode Method
pkiErrorCode
PKI_ErrorLookup General.ErrorLookup Method
pkiErrorLookup
PKI_FormatErrorMessage General.FormatErrorMessage Method errFormatErrorMessage
PKI_LastError General.LastError Method
pkiLastError
PKI_LicenceType General.LicenceType Method
pkiLicenceType
PKI_ModuleInfo General.ModuleInfo Method
pkiModuleInfo
PKI_ModuleName General.ModuleName Method
pkiModuleName
PKI_Platform General.Platform Method
pkiPlatform
PKI_PowerUpTests General.PowerUpTests Method
 
PKI_Version General.Version Method
pkiVersion
PRF_Bytes Prf.Bytes Method
prfBytes
PWD_Prompt
PWD_PromptEx
Pwd.Prompt Method
pwdPrompt
RNG_Bytes Rng.Bytes Method (Int32)
Rng.Bytes Method (Int32, Byte)
Rng.Bytes Method (Int32, String)
rngBytes
RNG_BytesWithPrompt Rng.BytesWithPrompt Method (Int32, Rng.Strength)
Rng.BytesWithPrompt Method (Int32, String, Rng.Strength)
 
RNG_Guid Rng.Guid Method
rngGuid
RNG_Initialize Rng.Initialize Method
Rng.InitializeEx Method
rngInitialize
rngInitializeEx
RNG_MakeSeedFile Rng.MakeSeedFile Method
 
RNG_Number Rng.Number Method
Rng.Octet Method
 
RNG_String - @deprecated Not applicable  
RNG_StringWithPrompt - @deprecated Not applicable  
RNG_Test Rng.Test Method
 
RNG_TestDRBGVS Rng.TestDrbgvs Method
 
RNG_UpdateSeedFile Rng.UpdateSeedFile Method
 
RSA_CheckKey Rsa.CheckKey Method (String)
Rsa.CheckKey Method (StringBuilder)
 
RSA_DecodeMsg Rsa.DecodeMsgForEncryption Method
Rsa.DecodeDigestForSignature Method
Rsa.DecodeMsgIso9796 Method
rsaDecodeMsg
RSA_Decrypt Rsa.Decrypt Method
rsaDecrypt
RSA_EncodeMsg Rsa.EncodeMsgForEncryption Method
Rsa.EncodeMsgForSignature Method
Rsa.EncodeDigestForSignature Method
Rsa.EncodeMsgIso9796 Method
rsaEncodeMsg
RSA_Encrypt Rsa.Encrypt Method
rsaEncrypt
RSA_FromXMLString Rsa.FromXMLString Method (String)
Rsa.FromXMLString Method (String, Rsa.XmlOptions)
Rsa.FromXMLString Method (String, Boolean)
rsaFromXMLString
RSA_GetPrivateKeyFromPFX Rsa.GetPrivateKeyFromPFX Method
 
RSA_GetPublicKeyFromCert - @deprecated Rsa.GetPublicKeyFromCert Method - @deprecated
 
RSA_KeyBits Rsa.KeyBits Method (String)
Rsa.KeyBits Method (StringBuilder)
rsaKeyBits
RSA_KeyBytes Rsa.KeyBytes Method (String)
Rsa.KeyBytes Method (StringBuilder)
rsaKeyBytes
RSA_KeyHashCode Rsa.KeyHashCode Method (String)
Rsa.KeyHashCode Method (StringBuilder)
 
RSA_KeyMatch Rsa.KeyMatch Method (String)
Rsa.KeyMatch Method (StringBuilder)
 
RSA_KeyValue Rsa.KeyValue Method
rsaKeyValue
RSA_MakeKeys - @deprecated Rsa.MakeKeys Method (String, String, Int32, Rsa.PublicExponent, Int32, String, Rsa.PbeOptions, Boolean, Byte[])
Rsa.MakeKeys Method (String, String, Int32, Rsa.PublicExponent, Int32, String, CipherAlgorithm, HashAlgorithm, Rsa.Format, Boolean)
rsaMakeKeys
RSA_MakeKeysXtd Rsa.MakeKeys Method (String, String, String, Int32, Rsa.PublicExponent, Rsa.PbeOptions, String, Rsa.Format, Boolean)
rsaMakeKeys
RSA_PublicKeyFromPrivate Rsa.PublicKeyFromPrivate Method
rsaPublicKeyFromPrivate
RSA_RawPrivate Rsa.RawPrivate Method (Byte[], String)
Rsa.RawPrivate Method (Byte[], String, Int32)
rsaRawPrivate
RSA_RawPublic Rsa.RawPublic Method (Byte[], String)
Rsa.RawPublic Method (Byte[], String, Int32)
rsaRawPublic
RSA_ReadAnyPrivateKey Rsa.ReadPrivateKey Method
rsaReadPrivateKey
rsaReadAnyPrivateKey
RSA_ReadAnyPublicKey Rsa.ReadPublicKey Method
rsaReadPublicKey
rsaReadAnyPublicKey
RSA_ReadEncPrivateKey - @deprecated Rsa.ReadEncPrivateKey Method - @deprecated
 
RSA_ReadPrivateKeyFromPFX - @deprecated Rsa.ReadPrivateKeyFromPFX Method - @deprecated
 
RSA_ReadPrivateKeyInfo - @deprecated Rsa.ReadPrivateKeyInfo Method - @deprecated
 
RSA_ReadPublicKey - @deprecated Rsa.ReadPublicKey Method
rsaReadPublicKey
RSA_SaveEncKey Rsa.SaveEncKey Method
rsaSaveEncKey
RSA_SaveEncPrivateKey Rsa.SaveEncPrivateKey Method (String, String, Int32, String, Rsa.PbeOptions, Rsa.Format)
Rsa.SaveEncPrivateKey Method (String, String, Int32, String, CipherAlgorithm, HashAlgorithm, Rsa.Format)
rsaSaveEncKey
RSA_SavePrivateKeyInfo Rsa.SavePrivateKeyInfo Method
rsaSaveKey
RSA_SavePublicKey Rsa.SavePublicKey Method
rsaSaveKey
RSA_ToXMLString
Rsa.ToXMLString Method (String, Rsa.XmlOptions)
rsaToXMLString
RSA_ToXMLStringEx Rsa.ToXMLString Method (String, String, Rsa.XmlOptions)
rsaToXMLStringEx
SIG_SignData Sig.SignData Method
Sig.SignDigest Method
sigSignData
SIG_SignFile Sig.SignFile Method
sigSignFile
SIG_VerifyData Sig.VerifyData Method
Sig.VerifyDigest Method
sigVerifyData
SIG_VerifyFile Sig.VerifyFile Method (String, String, String, SigAlgorithm, Sig.VerifyOpts)
 
SMIME_Extract Smime.Extract Method
 
SMIME_Query Smime.Query Method
smimeQuery
SMIME_Wrap Smime.Wrap Method
 
TDEA_B64Mode Tdea.Encrypt Method (String, String, Mode, String, EncodingBase)
Tdea.Decrypt Method (String, String, Mode, String, EncodingBase)
 
TDEA_BytesMode Tdea.Encrypt Method (Byte[], Byte[], Mode, Byte[])
Tdea.Decrypt Method (Byte[], Byte[], Mode, Byte[])
 
TDEA_File Tdea.FileEncrypt Method (String, String, Byte[], Mode, Byte[])
Tdea.FileDecrypt Method (String, String, Byte[], Mode, Byte[])
 
TDEA_HexMode Tdea.Encrypt Method (String, String, Mode, String)
Tdea.Decrypt Method (String, String, Mode, String)
 
WIPE_Data Wipe.Data Method
Wipe.String Method
wipeBytes
wipeString
WIPE_File Wipe.File Method
 
X509_CertExpiresOn X509.CertExpiresOn Method
 
X509_CertIssuedOn X509.CertIssuedOn Method
 
X509_CertIssuerName X509.CertIssuerName Method
 
X509_CertIsValidNow X509.CertIsValidNow Method
 
X509_CertRequest X509.CertRequest Method
 
X509_CertSerialNumber X509.CertSerialNumber Method
 
X509_CertSubjectName X509.CertSubjectName Method
 
X509_CertThumb X509.CertThumb Method
x509CertThumb
X509_CheckCertInCRL X509.CheckCertInCRL Method
 
X509_GetCertCountInP7Chain X509.GetCertCountInP7Chain Method
 
X509_GetCertFromP7Chain X509.GetCertFromP7Chain Method
 
X509_GetCertFromPFX X509.GetCertFromPFX Method
X509.GetP7ChainFromPFX Method
 
X509_HashIssuerAndSN X509.HashIssuerAndSN Method
x509HashIssuerAndSN
X509_KeyUsageFlags X509.KeyUsageFlags Method
 
X509_MakeCert X509.MakeCert Method
 
X509_MakeCertSelf X509.MakeCertSelf Method
 
X509_MakeCRL X509.MakeCRL Method
 
X509_QueryCert X509.QueryCert Method
x509QueryCert
X509_ReadCertStringFromP7Chain X509.ReadCertStringFromP7Chain Method
x509ReadCertStringFromP7Chain
X509_ReadCertStringFromPFX X509.ReadCertStringFromPFX Method
x509ReadCertStringFromPFX
X509_ReadStringFromFile X509.ReadStringFromFile Method
x509ReadStringFromFile
X509_SaveFileFromString X509.SaveFileFromString Method
 
X509_TextDump X509.TextDump Method
 
X509_TextDumpToString X509.TextDumpToString Method
x509TextDumpToString
X509_ValidatePath X509.ValidatePath Method
 
X509_VerifyCert X509.VerifyCert Method
 
XOF_Bytes Xof.Bytes Method
xofBytes

[Contents] [Index]

.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 below and also in the help file CryptoSysPKI.NET.chm available separately.

[Contents] [Index]

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.


Class index:    Asn1 | Cipher | Cms | Cnv | Compr | Ecc | General | Hash | Hmac | Hpke | Kdf | Ocsp | Pbe | Pem | Pfx | Prf | Pwd | Rng | Rsa | Sig | Smime | Tdea | Wipe | X509 | Xof

[Contents] [Index]


Asn1 Class

[Contents] [Index]

Cipher Class

[Contents] [Index]

Cms Class

[Contents] [Index]

Cnv Class

[Contents] [Index]

Compr Class

[Contents] [Index]

Ecc Class

[Contents] [Index]

General Class

[Contents] [Index]

Hash Class

[Contents] [Index]

Hmac Class

[Contents] [Index]

Hpke Class

[Contents] [Index]

Kdf Class

[Contents] [Index]

Ocsp Class

[Contents] [Index]

Pbe Class

[Contents] [Index]

Pem Class

[Contents] [Index]

Pfx Class

[Contents] [Index]

Prf Class

[Contents] [Index]

Pwd Class

[Contents] [Index]

Rng Class

[Contents] [Index]

Rsa Class

[Contents] [Index]

Sig Class

[Contents] [Index]

Smime Class

[Contents] [Index]

Tdea Class

[Contents] [Index]

Wipe Class

[Contents] [Index]

X509 Class

[Contents] [Index]

Xof Class

[Contents] [Index]

List of .Net Methods

Class index:    Asn1 | Cipher | Cms | Cnv | Compr | Ecc | General | Hash | Hmac | Hpke | Kdf | Ocsp | Pbe | Pem | Pfx | Prf | Pwd | Rng | Rsa | Sig | Smime | Tdea | Wipe | X509 | Xof

[Contents] [Index]


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
Option flags (optional)

Return Value

Zero if successful; otherwise it returns an error code

See Also

VB6/C equivalent: ASN1_TextDump

[Contents] [Index]


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
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

[Contents] [Index]


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

[Contents] [Index]


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
Cipher algorithm

Return Value

Block size in bytes

[Contents] [Index]


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
Cipher algorithm
mode
Type: 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

[Contents] [Index]


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
Cipher algorithm
mode
Type: Mode
Cipher mode
pad
Type: Padding
Padding method to use
opts
Type: 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

[Contents] [Index]


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
Cipher Algorithm
mode
Type: 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

[Contents] [Index]


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
Cipher Algorithm
mode
Type: Mode
Cipher Mode
pad
Type: Padding
Padding method to use
opts
Type: 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

[Contents] [Index]


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
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

[Contents] [Index]


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
Authenticated encryption algorithm.
opts
Type: 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

[Contents] [Index]


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
Cipher algorithm
mode
Type: 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

[Contents] [Index]


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
Cipher algorithm
mode
Type: Mode
Cipher mode
pad
Type: Padding
Padding method to use
opts
Type: 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

[Contents] [Index]


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
Cipher algorithm
mode
Type: 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

[Contents] [Index]


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
Cipher Algorithm
mode
Type: Mode
Cipher Mode
pad
Type: Padding
Padding method to use (optional)
opts
Type: 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

[Contents] [Index]


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
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

[Contents] [Index]


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
Authenticated encryption algorithm.
opts
Type: 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

[Contents] [Index]


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
Cipher Algorithm
mode
Type: Mode
Cipher Mode
pad
Type: Padding
Padding method to use (optional, ECB and CBC modes only, default=Pkcs5)
opts
Type: 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

Remarks

fileOut and fileIn must not be the same

See Also

VB6/C equivalent: CIPHER_FileDecrypt

[Contents] [Index]


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
Cipher Algorithm
mode
Type: Mode
Cipher Mode
pad
Type: Padding
Padding method to use (optional, ECB and CBC modes only, default=Pkcs5)
opts
Type: 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

Remarks

fileOut and fileIn must not be the same. The output file is in binary format.

See Also

VB6/C equivalent: CIPHER_FileDecrypt

[Contents] [Index]


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
Cipher Algorithm
mode
Type: Mode
Cipher Mode
pad
Type: Padding
Padding method to use (optional, ECB and CBC modes only, default=Pkcs5)
opts
Type: 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

Remarks

fileOut and fileIn must not be the same

See Also

VB6/C equivalent: CIPHER_FileEncrypt

[Contents] [Index]


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
Cipher Algorithm
mode
Type: Mode
Cipher Mode
pad
Type: Padding
Padding method to use (optional, ECB and CBC modes only, default=Pkcs5)
opts
Type: 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

Remarks

fileOut and fileIn must not be the same. The output file is in binary format.

See Also

VB6/C equivalent: CIPHER_FileEncrypt

[Contents] [Index]


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
Cipher algorithm

Return Value

Key size in bytes

[Contents] [Index]


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
Block cipher to use for wrapping

Return Value

Unwrapped key material (or empty array on error)

See Also

VB6/C equivalent: CIPHER_KeyUnwrap

[Contents] [Index]


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
Block cipher to use for wrapping

Return Value

Wrapped key (or empty array on error)

See Also

VB6/C equivalent: CIPHER_KeyWrap

[Contents] [Index]


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
Block cipher being used
pad
Type: Padding
Padding method to use (default is PKCS#5/#7)

Return Value

Padded data in byte array

See Also

VB6/C equivalent: PAD_BytesBlock

[Contents] [Index]


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
Block cipher being used
pad
Type: 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

[Contents] [Index]


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
Block cipher being used
pad
Type: 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

[Contents] [Index]


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
Block cipher being used
pad
Type: 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

[Contents] [Index]


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

[Contents] [Index]


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

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] [Index]


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

See Also

VB6/C equivalent: CMS_MakeComprData

[Contents] [Index]


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
Message digest algorithm to be used in signature [default=SHA-1]
advOptions
Type: Cms.SigDataOptions
Advanced option flags. See Cms.SigDataOptions.

Return Value

Zero if successful; otherwise it returns an error code

Remarks

RSASSA-PKCS1V1_5 only.

See Also

VB6/C equivalent: CMS_MakeDetachedSig

[Contents] [Index]


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
Content encryption algorithm [default=Triple DES].
advOptions
Type: Cms.EnvDataOptions
Advanced options. See Cms.EnvDataOptions.

Return Value

Number of successful recipients or a negative error code.

See Also

VB6/C equivalent: CMS_MakeEnvData

[Contents] [Index]


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
Content encryption algorithm [default=Triple DES]. Deprecated: use contEncrAlg.
keyEncrAlg
Type: Cms.KeyEncrAlgorithm
Key encryption algorithm for ktri type [default=RSAES-PKCS-v1_5)]
hashAlg
Type: 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
Advanced options. See Cms.EnvDataOptions.
kdfAlg
Type: Kdf.KdfAlg
Key derivation function (KDF) for ECDH key agreement scheme (where applicable)
keyWrapAlg
Type: 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
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.

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

[Contents] [Index]


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
Content encryption algorithm [default=Triple DES]. Deprecated: use contEncrAlg.
keyEncrAlg
Type: Cms.KeyEncrAlgorithm
Key encryption algorithm for ktri type [default=RSAES-PKCS-v1_5)]
hashAlg
Type: 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
Advanced options. See Cms.EnvDataOptions.
kdfAlg
Type: Kdf.KdfAlg
Key derivation function (KDF) for ECDH key agreement scheme (where applicable)
keyWrapAlg
Type: 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
Alternative way to specify content encryption algorithm with more options. Takes precedence over cipherAlg.

Return Value

Number of successful recipients or negative error code

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

[Contents] [Index]


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
Content encryption algorithm [default=Triple DES]
advOptions
Type: Cms.EnvDataOptions
Advanced options. See Cms.EnvDataOptions.

Return Value

Number of successful recipients or negative error code

See Also

VB6/C equivalent: CMS_MakeEnvDataFromString

[Contents] [Index]


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
Content encryption algorithm [default=Triple DES]. Deprecated: use contEncrAlg.
keyEncrAlg
Type: Cms.KeyEncrAlgorithm
Key encryption algorithm [default=rsaEncryption)]
hashAlg
Type: 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
Advanced options. See Cms.EnvDataOptions.
kdfAlg
Type: Kdf.KdfAlg
Key derivation function (KDF) for ECDH key agreement scheme (where applicable)
keyWrapAlg
Type: 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
Alternative way to specify content encryption algorithm with more options. Takes precedence over cipherAlg.

Return Value

Number of successful recipients or negative error code

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

[Contents] [Index]


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
Signature algorithm.
advOptions
Type: Cms.SigDataOptions
Advanced option flags. See Cms.SigDataOptions.

Return Value

Zero if successful; otherwise it returns an error code

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

[Contents] [Index]


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
Message digest algorithm to be used in signature [default=SHA-1].
advOptions
Type: Cms.SigDataOptions
Advanced option flags. See Cms.SigDataOptions.

Return Value

Zero if successful; otherwise it returns an error code

Remarks

RSASSA-PKCS1V1_5 only.

See Also

VB6/C equivalent: CMS_MakeSigData

[Contents] [Index]


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
Signature algorithm.
advOptions
Type: Cms.SigDataOptions
Advanced option flags. See Cms.SigDataOptions.

Return Value

Zero if successful; otherwise it returns an error code

See Also

VB6/C equivalent: CMS_MakeSigDataFromBytes

[Contents] [Index]


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
Output format (default = binary)

Return Value

Zero if successful; otherwise it returns an error code

Remarks

RSASSA-PKCS1V1_5 only.

See Also

VB6/C equivalent: CMS_MakeSigDataFromSigValue

[Contents] [Index]


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
Message digest algorithm to be used in signature [default=SHA-1]
advOptions
Type: Cms.SigDataOptions
Advanced option flags. See Cms.SigDataOptions.

Return Value

Zero if successful; otherwise it returns an error code

Remarks

RSASSA-PKCS1V1_5 only.

See Also

VB6/C equivalent: CMS_MakeSigDataFromSigValue

[Contents] [Index]


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
Signature algorithm.
advOptions
Type: Cms.SigDataOptions
Advanced option flags. See Cms.SigDataOptions.

Return Value

Zero if successful; otherwise it returns an error code

See Also

VB6/C equivalent: CMS_MakeSigDataFromString

[Contents] [Index]


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
Message digest algorithm to be used in signature [default=SHA-1]
advOptions
Type: Cms.SigDataOptions
Advanced option flags. See Cms.SigDataOptions.

Return Value

Zero if successful; otherwise it returns an error code

Remarks

RSASSA-PKCS1V1_5 only.

See Also

VB6/C equivalent: CMS_MakeSigDataFromString

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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
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

See Also

VB6/C equivalent: CMS_ReadComprData

[Contents] [Index]


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

[Contents] [Index]


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
Use Cms.ReadOptions for faster handling of large files (binary only).

Return Value

Zero if successful; otherwise it returns an error code.

See Also

VB6/C equivalent: CMS_ReadEnvData

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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
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.

See Also

VB6/C equivalent: CMS_ReadSigData

[Contents] [Index]


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

[Contents] [Index]


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
Use for BigFile option, otherwise ignored

Return Value

Zero if successfully verified; otherwise it returns a non-zero error code

See Also

VB6/C equivalent: CMS_VerifySigData

[Contents] [Index]


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

[Contents] [Index]


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] [Index]


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
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

[Contents] [Index]


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:

0Not valid UTF-8
1Valid UTF-8, all chars are 7-bit ASCII
2Valid UTF-8, contains at least one multi-byte character equivalent to 8-bit ANSI
3Valid 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

[Contents] [Index]


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:

0Not valid UTF-8
1Valid UTF-8, all chars are 7-bit ASCII
2Valid UTF-8, contains at least one multi-byte character equivalent to 8-bit ANSI
3Valid 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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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] [Index]


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
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

[Contents] [Index]


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
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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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] [Index]


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] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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
name of elliptic curve
password
password to be used for the encrypted key file.
pbes
Type: 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
(optional) Format to save file [default = DER binary]

Return Value

Zero if successful or non-zero error code

Remarks

Valid name-value pairs for paramString are:

count=integerTo set the iteration count used in the PBKDF2 method, e.g. "count=5000;" [default=2048].
prf=hmac-nameTo change the HMAC algorithm used in the PBKDF2 method, e.g. "prf=hmacwithSHA256;" [default=hmacwithSHA1].
rngseed=stringTo 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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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
name of the elliptic curve
keyType
Type: 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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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
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
Format to save file [default = DER binary]

Return Value

Zero if successful or non-zero error code

Remarks

Valid name-value pairs for paramString are:

count=integerTo set the iteration count used in the PBKDF2 method, e.g. "count=5000;" [default=2048].
prf=hmac-nameTo 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

[Contents] [Index]


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
Key structure for private key (ignored for public)
fileFormat
Type: 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

See Also

VB6/C equivalent: ECC_SaveKey

[Contents] [Index]


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

[Contents] [Index]


General.ErrorCode Method

Return the error code 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

[Contents] [Index]


General.ErrorLookup Method

Return a description of an error code.

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

[Contents] [Index]


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] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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
Hash algorithm to be used

Return Value

Message digest in byte format

See Also

VB6/C equivalent: HASH_Bytes

[Contents] [Index]


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
Hash algorithm to be used

Return Value

Message digest in byte format

See Also

VB6/C equivalent: HASH_File

[Contents] [Index]


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
Hash algorithm to be used

Return Value

Message digest HASH(HASH(m)) in byte format

See Also

VB6/C equivalent: HASH_Bytes

[Contents] [Index]


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
Hash algorithm to be used

Return Value

Message digest in hex-encoded format

See Also

VB6/C equivalent: HASH_HexFromBytes

[Contents] [Index]


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
Hash algorithm to be used

Return Value

Message digest in hex-encoded format

See Also

VB6/C equivalent: HASH_HexFromFile

[Contents] [Index]


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
Hash algorithm to be used

Return Value

Message digest in hex-encoded format

See Also

VB6/C equivalent: HASH_HexFromHex

[Contents] [Index]


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
Hash algorithm to be used

Return Value

Message digest in hex-encoded format

See Also

VB6/C equivalent: HASH_HexFromBytes

[Contents] [Index]


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
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

[Contents] [Index]


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
Hash algorithm

Return Value

Length of the hash function output in bytes.

See Also

VB6/C equivalent: HASH_Length

[Contents] [Index]


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
Hash algorithm to be used

Return Value

HMAC in byte format

See Also

VB6/C equivalent: HMAC_Bytes

[Contents] [Index]


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
Hash algorithm to be used

Return Value

HMAC in hex-encoded format

See Also

VB6/C equivalent: HMAC_HexFromBytes

[Contents] [Index]


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
Hash algorithm to be used

Return Value

HMAC in hex-encoded format

See Also

VB6/C equivalent: HMAC_HexFromHex

[Contents] [Index]


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
Curve name
opts
Type: 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 curveKDF
P-256HKDF-SHA256
P-384HKDF-SHA384
P-521HKDF-SHA512
X25519HKDF-SHA256
X448HKDF-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

[Contents] [Index]


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
ECDH curve used in scheme
aeadAlg
Type: 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

[Contents] [Index]


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
ECDH curve used in scheme
aeadAlg
Type: 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

[Contents] [Index]


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
Key derivation function to use.
hashAlg
Type: 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

[Contents] [Index]


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
Key wrap algorithm (required, cannot be Default)
kdfAlg
Type: Kdf.KdfAlg
Key derivation function to use.
hashAlg
Type: 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

[Contents] [Index]


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
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

[Contents] [Index]


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

[Contents] [Index]


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
Hash algorithm to use in HMAC PRF (default is SHA-1)

Return Value

Key in byte[] format

See Also

VB6/C equivalent: PBE_Kdf2

[Contents] [Index]


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
Hash algorithm to use in HMAC PRF (default is SHA-1)

Return Value

Key in hex format

See Also

VB6/C equivalent: PBE_Kdf2Hex

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

See Also

VB6/C equivalent: PEM_FileFromBinFile

[Contents] [Index]


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

See Also

VB6/C equivalent: PEM_FileToBinFile

[Contents] [Index]


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
Specialist options

Return Value

Zero if successful or a non-zero error code.

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

[Contents] [Index]


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

[Contents] [Index]


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
PRF algorithm.
customStr
Customization string (optional).

Return Value

Output data in byte array.

See Also

VB6/C equivalent: PRF_Bytes

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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
Estimated security strength (default=112 bits)

Return Value

Array of random bytes

See Also

VB6/C equivalent: RNG_BytesWithPrompt

[Contents] [Index]


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
Required security strength

Return Value

Array of random bytes

See Also

VB6/C equivalent: RNG_BytesWithPrompt

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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
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.

See Also

VB6/C equivalent: RNG_Initialize

[Contents] [Index]


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
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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

Remarks

A private key is also validated for consistency.

See Also

VB6/C equivalent: RSA_CheckKey

[Contents] [Index]


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

Remarks

A private key is also validated for consistency.

See Also

VB6/C equivalent: RSA_CheckKey

[Contents] [Index]


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

[Contents] [Index]


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
Encoding method used

Return Value

Decoded message

See Also

VB6/C equivalent: RSA_DecodeMsg

[Contents] [Index]


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

[Contents] [Index]


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
Encoding method [optional, default = EME.PKCSv1_5]
hashAlg
Type: Rsa.HashAlg
Hash function for EME-OAEP encoding, otherwise ignored.
advOpts
Type: 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

[Contents] [Index]


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
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

[Contents] [Index]


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
Encoding method to use

Return Value

Encoded message block

See Also

VB6/C equivalent: RSA_EncodeMsg

[Contents] [Index]


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
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

[Contents] [Index]


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

[Contents] [Index]


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
Encoding method [optional, default = EME.PKCSv1_5]
hashAlg
Type: Rsa.HashAlg
Hash function for EME-OAEP encoding, otherwise ignored.
advOpts
Type: 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

[Contents] [Index]


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

[Contents] [Index]


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
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

[Contents] [Index]


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

[Contents] [Index]


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

See Also

VB6/C equivalent: RSA_GetPrivateKeyFromPFX

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

See Also

VB6/C equivalent: RSA_KeyMatch

[Contents] [Index]


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

See Also

VB6/C equivalent: RSA_KeyMatch

[Contents] [Index]


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

[Contents] [Index]


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
Exponent (Fermat Prime)
iterCount
Iteration count for encrypted private key
password
Password string for encrypted private key
cipherAlg
Type: CipherAlgorithm
Block cipher to use for encryption scheme [default = des-ede3-cbc]
hashAlg
Type: HashAlgorithm
Hash function to use in PRF HMAC algorithm [default = hmacWithSHA1]
fileFormat
Type: Rsa.Format
Format to save file [default = DER binary]
showProgress
Indicate progress in console

Return Value

Zero if successful or non-zero error code

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

[Contents] [Index]


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
Exponent (Fermat Prime)
iterCount
Iteration count for encrypted private key
password
Password string for encrypted private key
cryptOption
Type: 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

See Also

VB6/C equivalent: RSA_MakeKeys

[Contents] [Index]


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
Exponent [default=65537=F4]
pbes
Type: 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
Format to save file [default = DER binary]
showProgress
Indicate progress in console

Return Value

Zero if successful or non-zero error code

Remarks

Valid name-value pairs for paramString are:

count=integerTo set the iteration count used in the PBKDF2 method, e.g. "count=5000;" [default=2048].
prf=hmac-nameTo 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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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
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
File format

Return Value

If successful, the return value is zero; otherwise it returns a nonzero error code

Remarks

Valid name-value pairs for paramString are:

count=integerTo set the iteration count used in the PBKDF2 method, e.g. "count=5000;" [default=2048].
prf=hmac-nameTo 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

[Contents] [Index]


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
Block cipher to use for encryption scheme [default = des-ede3-cbc]
hashAlg
Type: HashAlgorithm
Hash function to use in PRF HMAC algorithm [default = hmacWithSHA1]
format
Type: Rsa.Format
File format

Return Value

If successful, the return value is zero; otherwise it returns a nonzero error code

See Also

VB6/C equivalent: RSA_SaveEncPrivateKey

[Contents] [Index]


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
Type of password-based encryption to use [default = pbeWithSHAAnd3-KeyTripleDES-CBC]
format
Type: Rsa.Format
File format

Return Value

If successful, the return value is zero; otherwise it returns a nonzero error code

See Also

VB6/C equivalent: RSA_SaveEncPrivateKey

[Contents] [Index]


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
File format

Return Value

If successful, the return value is zero; otherwise it returns a nonzero error code

Remarks

Do not use for a production key.

See Also

VB6/C equivalent: RSA_SavePrivateKeyInfo

[Contents] [Index]


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
File format

Return Value

If successful, the return value is zero; otherwise it returns a nonzero error code

See Also

VB6/C equivalent: RSA_SavePublicKey

[Contents] [Index]


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
Option flags: set as zero for defaults.

Return Value

XML string or empty string on error

See Also

VB6/C equivalent: RSA_ToXMLString

[Contents] [Index]


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
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

[Contents] [Index]


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
Signature algorithm

Return Value

Hash algorithm used in sigAlg

[Contents] [Index]


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
Signature algorithm to be used
sigOpts
Type: Sig.SigOptions
(optional) Options for ECDSA and RSA-PSS signatures
sigEncoding
Type: 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

[Contents] [Index]


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
Signature algorithm to be used
sigOpts
Type: Sig.SigOptions
(optional) Options for ECDSA and RSA-PSS signatures
sigEncoding
Type: 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

[Contents] [Index]


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
Signature algorithm to be used
sigOpts
Type: Sig.SigOptions
(optional) Options for ECDSA and RSA-PSS signatures
sigEncoding
Type: 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

[Contents] [Index]


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
Signature algorithm used to create signature.
opts
Type: Sig.VerifyOpts
(optional) Advanced options for RSA-PSS only.

Return Value

Zero (0) if the signature is valid; otherwise a negative error code.

Remarks

Any valid encodings of the signature value are detected automatically.

See Also

VB6/C equivalent: SIG_VerifyData

[Contents] [Index]


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
Signature algorithm used to create signature.
opts
Type: Sig.VerifyOpts
Advanced options for RSA-PSS only (optional)

Return Value

Zero (0) if the signature is valid; otherwise a negative error code.

Remarks

Any valid encodings of the signature value are detected automatically.

See Also

VB6/C equivalent: SIG_VerifyData

[Contents] [Index]


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
Signature algorithm used to create signature.
opts
Type: Sig.VerifyOpts
Advanced options for RSA-PSS only (optional)

Return Value

Zero (0) if the signature is valid; otherwise a negative error code.

Remarks

Any valid encodings of the signature value are detected automatically.

See Also

VB6/C equivalent: SIG_VerifyFile

[Contents] [Index]


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
Options

Return Value

A positive number giving the size of the output file in bytes; otherwise it returns an error code

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

[Contents] [Index]


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

[Contents] [Index]


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
Options

Return Value

A positive number giving the size of the output file in bytes; otherwise it returns an error code

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

[Contents] [Index]


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
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

[Contents] [Index]


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
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

[Contents] [Index]


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
Cipher Mode
ivStr
Encoded IV representing exactly 8 bytes or "" for ECB mode
encodingBase
Type: 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

[Contents] [Index]


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
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

[Contents] [Index]


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
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

[Contents] [Index]


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
Cipher Mode
ivStr
Encoded IV representing exactly 8 bytes or "" for ECB mode
encodingBase
Type: 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

[Contents] [Index]


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
Cipher Mode
iv
IV of exactly 8 bytes or null for ECB mode

Return Value

0 if successful or non-zero error code

Remarks

fileOut and fileIn must not be the same

See Also

VB6/C equivalent: TDEA_File

[Contents] [Index]


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
Cipher Mode
ivHex
Hex-encoded IV or "" for ECB mode

Return Value

0 if successful or non-zero error code

Remarks

fileOut and fileIn must not be the same. The output file is in binary format.

[Contents] [Index]


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
Cipher Mode
iv
IV of exactly 8 bytes or null for ECB mode

Return Value

0 if successful or non-zero error code

Remarks

fileOut and fileIn must not be the same

See Also

VB6/C equivalent: TDEA_File

[Contents] [Index]


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
Cipher Mode
ivHex
Hex-encoded IV or "" for ECB mode

Return Value

0 if successful or non-zero error code

Remarks

fileOut and fileIn must not be the same. The output file is in binary format.

[Contents] [Index]


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

[Contents] [Index]


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
Options (optional, default = DOD 7-pass)

Return Value

true if successful; false if fails

See Also

VB6/C equivalent: WIPE_File

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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
Signature algorithm (must match key type)
opts
Type: X509.CsrOptions
Option flags: set as zero for defaults.

Return Value

Zero if successful or a non-zero error code

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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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
HashAlgorithm

Return Value

String containing the message digest in hexadecimal format

See Also

VB6/C equivalent: X509_CertThumb

[Contents] [Index]


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.

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

[Contents] [Index]


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.

See Also

VB6/C equivalent: X509_GetCertCountInP7Chain

[Contents] [Index]


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.

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

[Contents] [Index]


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

Remarks

Only supports weak 40-bit RC2 encryption for the certificate.

See Also

VB6/C equivalent: X509_GetCertFromPFX

[Contents] [Index]


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

Remarks

Only supports weak 40-bit RC2 encryption for the certificate.

See Also

VB6/C equivalent: X509_GetCertFromPFX

[Contents] [Index]


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
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

[Contents] [Index]


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

Remarks

See X509.KeyUsageOptions.

See Also

VB6/C equivalent: X509_KeyUsageFlags

[Contents] [Index]


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
Key usage options
password
For issuer's private key, if encrypted.
sigAlg
Type: SigAlgorithm
Signature algorithm to sign certificate.
options
Type: X509.CertOptions
Option flags: set as zero for defaults.

Return Value

Zero if successful or a non-zero error code

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

[Contents] [Index]


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
Key usage options
password
For issuer's private key
sigAlg
Type: SigAlgorithm
Signature algorithm to sign certificate.
options
Type: X509.CertOptions
Option flags: set as zero for defaults.

Return Value

Zero if successful or a non-zero error code

See Also

VB6/C equivalent: X509_MakeCertSelf

[Contents] [Index]


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:
sigAlg
Type: SigAlgorithm
Signature algorithm.
opts
Type: X509.CrlOptions
Options

Return Value

If successful, the return value is zero; otherwise it returns a non-zero error code.

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

[Contents] [Index]


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
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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

[Contents] [Index]


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

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

[Contents] [Index]


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
Options for output (optional)

Return Value

If successful, the return value is zero; otherwise it returns a nonzero error code.

Remarks

The notation [!] denotes a critical extension, e.g. Key Usage[!]:.

See Also

VB6/C equivalent: X509_TextDump

[Contents] [Index]


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
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

[Contents] [Index]


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.

See Also

VB6/C equivalent: X509_ValidatePath

[Contents] [Index]


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.

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

[Contents] [Index]


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
XOF algorithm.

Return Value

Output data in byte array.

See Also

VB6/C equivalent: XOF_Bytes

[Contents] [Index]


Enumerations in .NET

[Contents] [Index]


AeadAlgorithm Enumeration

Authenticated encryption algorithm.

Syntax

[C#]
public enum AeadAlgorithm
[VB.NET]
Public Enumeration AeadAlgorithm

Members

Member nameDescription
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] [Index]


Asn1.Options Enumeration

Options for ASN.1 methods

Syntax

[C#]
[FlagsAttribute]
public enum Options
[VB.NET]
<FlagsAttribute> _
Public Enumeration Options

Members

Member nameDescription
Default
Default options
NoComments
Hide the comments [default=show comments]
AddLevels
Show level numbers [default=hide level numbers]

[Contents] [Index]


CipherAlgorithm Enumeration

Block Cipher Algorithm

Syntax

[C#]
public enum CipherAlgorithm
[VB.NET]
Public Enumeration CipherAlgorithm

Members

Member nameDescription
Tdea
Triple DES (TDEA, 3DES, des-ede3)
Aes128
AES-128
Aes192
AES-192
Aes256
AES-256

[Contents] [Index]


Cipher.Opts Enumeration

Advanced options

Syntax

[C#]
[FlagsAttribute]
public enum Opts
[VB.NET]
<FlagsAttribute> _
Public Enumeration Opts

Members

Member nameDescription
Default
Default options
PrefixIV
Prefix (prepend) the IV before the ciphertext in the output (ignored for ECB mode)

[Contents] [Index]


Cms.ComprDataOptions Enumeration

Advanced options for CMS compressed-data objects

Syntax

[C#]
[FlagsAttribute]
public enum ComprDataOptions
[VB.NET]
<FlagsAttribute> _
Public Enumeration ComprDataOptions

Members

Member nameDescription
Default
Default options.
NoInflate
Extract the compressed data as is without inflation.

[Contents] [Index]


Cms.ContentEncrAlg Enumeration

Content encryption algorithm.

Syntax

[C#]
public enum ContentEncrAlg
[VB.NET]
Public Enumeration ContentEncrAlg

Members

Member nameDescription
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] [Index]


Cms.EnvDataOptions Enumeration

Advanced options for CMS enveloped-data objects.

Syntax

[C#]
[FlagsAttribute]
public enum EnvDataOptions
[VB.NET]
<FlagsAttribute> _
Public Enumeration EnvDataOptions

Members

Member nameDescription
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] [Index]


Cms.Format Enumeration

Output format.

Syntax

[C#]
public enum Format
[VB.NET]
Public Enumeration Format

Members

Member nameDescription
Default
Default output format
Binary
Binary output (default)
FormatBase64
Output is encoded in base64 (default = binary).

[Contents] [Index]


Cms.KeyEncrAlgorithm Enumeration

Key encryption algorithm for key transport (ktri) technique

Syntax

[C#]
public enum KeyEncrAlgorithm
[VB.NET]
Public Enumeration KeyEncrAlgorithm

Members

Member nameDescription
Default
Default
Rsa_Pkcs1v1_5
RSAES-PKCS-v1_5 (rsaEncryption)
Rsa_Oaep
RSAES-OAEP

[Contents] [Index]


Cms.ReadOptions Enumeration

Options for reading CMS objects.

Syntax

[C#]
[FlagsAttribute]
public enum ReadOptions
[VB.NET]
<FlagsAttribute> _
Public Enumeration ReadOptions

Members

Member nameDescription
None
Default options.
BigFile
Use to speed up the encryption of large files (binary file input only).

[Contents] [Index]


Cms.SigAlg Enumeration

Signature algorithm for CMS signed-data objects.

Syntax

[C#]
public enum SigAlg
[VB.NET]
Public Enumeration SigAlg

Members

Member nameDescription
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] [Index]


Cms.SigDataOptions Enumeration

Advanced options for CMS signed-data objects

Syntax

[C#]
[FlagsAttribute]
public enum SigDataOptions
[VB.NET]
<FlagsAttribute> _
Public Enumeration SigDataOptions

Members

Member nameDescription
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] [Index]


Cnv.EncodingConversion Enumeration

Conversion directions for ByteEncoding.

Syntax

[C#]
public enum EncodingConversion
[VB.NET]
Public Enumeration EncodingConversion

Members

Member nameDescription
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] [Index]


Cnv.EndianNess Enumeration

Byte order.

Syntax

[C#]
public enum EndianNess
[VB.NET]
Public Enumeration EndianNess

Members

Member nameDescription
BigEndian
Most-significant byte first
LittleEndian
Least-significant byte first

[Contents] [Index]


Ecc.CurveName Enumeration

Supported curve names.

Syntax

[C#]
public enum CurveName
[VB.NET]
Public Enumeration CurveName

Members

Member nameDescription
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] [Index]


Ecc.Format Enumeration

Format for output files.

Syntax

[C#]
public enum Format
[VB.NET]
Public Enumeration Format

Members

Member nameDescription
Default
Default = binary
Binary
Binary DER-encoded
PEM
PEM-encoded text file

[Contents] [Index]


Ecc.KeyType Enumeration

Key type for unencrypted key file.

Syntax

[C#]
public enum KeyType
[VB.NET]
Public Enumeration KeyType

Members

Member nameDescription
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] [Index]


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 nameDescription
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] [Index]


EncodingBase Enumeration

Base for encoding methods

Syntax

[C#]
public enum EncodingBase
[VB.NET]
Public Enumeration EncodingBase

Members

Member nameDescription
Base64
Base64 encoding
Base16
Base16 encoding (i.e. hexadecimal)

[Contents] [Index]


HashAlgorithm Enumeration

Message Digest Hash Algorithm

Syntax

[C#]
public enum HashAlgorithm
[VB.NET]
Public Enumeration HashAlgorithm

Members

Member nameDescription
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] [Index]


Hpke.AeadAlg Enumeration

AEAD functions supported for HPKE

Syntax

[C#]
public enum AeadAlg
[VB.NET]
Public Enumeration AeadAlg

Members

Member nameDescription
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] [Index]


Hpke.CurveName Enumeration

Supported ECDH curves for HPKE

Syntax

[C#]
public enum CurveName
[VB.NET]
Public Enumeration CurveName

Members

Member nameDescription
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] [Index]


Hpke.OutputOpts Enumeration

Options to format or re-encode output.

Syntax

[C#]
public enum OutputOpts
[VB.NET]
Public Enumeration OutputOpts

Members

Member nameDescription
Default
Default = output as ephemeral "internal" key string.
KeyAsHex
Output key in hex format compatible with test vectors in [RFC9180]

[Contents] [Index]


Kdf.HashAlg Enumeration

Hash algorithms for KDF

Syntax

[C#]
public enum HashAlg
[VB.NET]
Public Enumeration HashAlg

Members

Member nameDescription
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] [Index]


Kdf.KdfAlg Enumeration

Key derivation functions

Syntax

[C#]
public enum KdfAlg
[VB.NET]
Public Enumeration KdfAlg

Members

Member nameDescription
X963
ANSI-X9.63-KDF key derivation function (default)
Hkdf
HMAC-based Key Derivation Function (HKDF) from [RFC5869]

[Contents] [Index]


Kdf.KeyWrapAlg Enumeration

Key wrap algorithms for KDF

Syntax

[C#]
public enum KeyWrapAlg
[VB.NET]
Public Enumeration KeyWrapAlg

Members

Member nameDescription
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] [Index]


Mode Enumeration

Cipher Mode

Syntax

[C#]
public enum Mode
[VB.NET]
Public Enumeration Mode

Members

Member nameDescription
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] [Index]


Padding Enumeration

Block Cipher Padding

Syntax

[C#]
public enum Padding
[VB.NET]
Public Enumeration Padding

Members

Member nameDescription
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] [Index]


Pfx.Options Enumeration

Specialist options.

Syntax

[C#]
[FlagsAttribute]
public enum Options
[VB.NET]
<FlagsAttribute> _
Public Enumeration Options

Members

Member nameDescription
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] [Index]


Prf.Alg Enumeration

Pseudorandom function (PRF) algorithm.

Syntax

[C#]
public enum Alg
[VB.NET]
Public Enumeration Alg

Members

Member nameDescription
Kmac128
KMAC128 as per NIST SP 800-185
Kmac256
KMAC256 as per NIST SP 800-185

[Contents] [Index]


Rng.Options Enumeration

Rng options

Syntax

[C#]
public enum Options
[VB.NET]
Public Enumeration Options

Members

Member nameDescription
Default
Default option
NoIntelDrng
Turn off support for INTEL(R) DRNG for the current session.

[Contents] [Index]


Rng.Strength Enumeration

Required security strength for user-prompted entropy

Syntax

[C#]
public enum Strength
[VB.NET]
Public Enumeration Strength

Members

Member nameDescription
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] [Index]


Rsa.AdvOptions Enumeration

Advanced options.

Syntax

[C#]
[FlagsAttribute]
public enum AdvOptions
[VB.NET]
<FlagsAttribute> _
Public Enumeration AdvOptions

Members

Member nameDescription
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] [Index]


Rsa.EME Enumeration

Encoding method for encryption.

Syntax

[C#]
public enum EME
[VB.NET]
Public Enumeration EME

Members

Member nameDescription
PKCSv1_5
EME-PKCS1-v1_5 encoding method
OAEP
EME-OAEP encoding method

Remarks

See PKCS#1 v2.2 [RFC8017]

[Contents] [Index]


Rsa.Format Enumeration

Format for saved RSA key.

Syntax

[C#]
public enum Format
[VB.NET]
Public Enumeration Format

Members

Member nameDescription
Default
Default = Binary
Binary
Binary DER-encoded
PEM
PEM Format
SSL
PEM format compatible with OpenSSL

[Contents] [Index]


Rsa.HashAlg Enumeration

Hash function for OAEP encoding.

Syntax

[C#]
public enum HashAlg
[VB.NET]
Public Enumeration HashAlg

Members

Member nameDescription
Sha1
SHA-1 (default)
Sha224
SHA-224
Sha256
SHA-256
Sha384
SHA-384
Sha512
SHA-512

[Contents] [Index]


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 nameDescription
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] [Index]


Rsa.PublicExponent Enumeration

Choices for public exponent (e)

Syntax

[C#]
public enum PublicExponent
[VB.NET]
Public Enumeration PublicExponent

Members

Member nameDescription
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] [Index]


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 nameDescription
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] [Index]


SigAlgorithm Enumeration

Signature algorithm

Syntax

[C#]
public enum SigAlgorithm
[VB.NET]
Public Enumeration SigAlgorithm

Members

Member nameDescription
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] [Index]


Sig.Encoding Enumeration

Encodings for signature output.

Syntax

[C#]
public enum Encoding
[VB.NET]
Public Enumeration Encoding

Members

Member nameDescription
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] [Index]


Sig.SigOptions Enumeration

Specialist options for signatures.

Syntax

[C#]
[FlagsAttribute]
public enum SigOptions
[VB.NET]
<FlagsAttribute> _
Public Enumeration SigOptions

Members

Member nameDescription
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] [Index]


Sig.VerifyOpts Enumeration

Specialist options for verifying a signature.

Syntax

[C#]
[FlagsAttribute]
public enum VerifyOpts
[VB.NET]
<FlagsAttribute> _
Public Enumeration VerifyOpts

Members

Member nameDescription
Default
Use default options.
Mgf1Sha1
RSA-PSS only: Force the MGF hash function to be SHA-1 [default = same as signature hash algorithm]

[Contents] [Index]


Smime.Options Enumeration

Options for S/MIME methods

Syntax

[C#]
[FlagsAttribute]
public enum Options
[VB.NET]
<FlagsAttribute> _
Public Enumeration Options

Members

Member nameDescription
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] [Index]


Wipe.Options Enumeration

Wipe options.

Syntax

[C#]
public enum Options
[VB.NET]
Public Enumeration Options

Members

Member nameDescription
Default
Default options (DOD 7-pass)
Dod7Pass
DOD 7-pass (default)
Simple
Overwrite with single pass of zero bytes (quicker but less secure).

[Contents] [Index]


X509.CertOptions Enumeration

Options to create X.509 certificate.

Syntax

[C#]
[FlagsAttribute]
public enum CertOptions
[VB.NET]
<FlagsAttribute> _
Public Enumeration CertOptions

Members

Member nameDescription
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] [Index]


X509.CrlOptions Enumeration

Options to create Certificate Revocation List (CRL)

Syntax

[C#]
[FlagsAttribute]
public enum CrlOptions
[VB.NET]
<FlagsAttribute> _
Public Enumeration CrlOptions

Members

Member nameDescription
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] [Index]


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 nameDescription
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] [Index]


X509.KeyUsageOptions Enumeration

Options for key usage in certificate

Syntax

[C#]
[FlagsAttribute]
public enum KeyUsageOptions
[VB.NET]
<FlagsAttribute> _
Public Enumeration KeyUsageOptions

Members

Member nameDescription
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] [Index]


X509.OutputOpts Enumeration

Options to format or re-encode output.

Syntax

[C#]
[FlagsAttribute]
public enum OutputOpts
[VB.NET]
<FlagsAttribute> _
Public Enumeration OutputOpts

Members

Member nameDescription
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] [Index]


Xof.Alg Enumeration

eXtendable-Output Function (XOF) algorithm.

Syntax

[C#]
public enum Alg
[VB.NET]
Public Enumeration Alg

Members

Member nameDescription
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] [Index]


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 function or the 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 function or 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 function or 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] [Index]

Acknowledgements

The source code used in CryptoSys PKI Pro is original code written by David Ireland except for the following:

Thanks to the guys at NullSoft 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].

[Contents] [Index]

Primary References

These are the primary references we used to create CryptoSys PKI Pro.

[Contents] [Index]

Bibliography

Other works we referred to in creating CryptoSys PKI Pro.

[Contents] [Index]

Index

'Hello world' programs
.NET Classes and Methods
.NET Help File
A caution about insecure default algorithms
Acknowledgements
Action if a self-test fails
Add an arbitrary X.509 Extension
Additional security attributes New in v12.4
AOC policy for X.509 content
ASN.1 analysis functions
ASN.1 objects: binary DER- and BER-encoded files vs PEM-encoded text files
Asn1 Class
AUTACK messages and ISO/IEC 9796-1 signatures
Authenticated Encryption with Associated Data (AEAD)
Base64 alternative for X.509 certificates
Base64 and PEM string alternatives for CMS objects
Base64url encoding and JSON Web Signatures (JWS)
Bibliography
Block Cipher Functions
C++ (STL) Functions
C/C++ users must add one to this value...
Can you read a key in compressed representation?
Cautions for C/C++ Users
Certificate Revocation List (CRL) functions
Changes in earlier versions
Cipher Class
CMS AuthEnvelopedData objects
Cms Class
CMS Content Types
CMS EnvelopedData objects
CMS functions
CMS SignedData objects
Cnv Class
Combining bitwise options
Compiling with C
Compr Class
Compression functions
Conditional Tests
Continuous random number generator test:
Conventions in this document
Conversion functions
Converting strings to bytes and vice versa
Converting VB6 to VB.NET
Copyright Notice
Core VBA/VB6 functions vs better wrapper functions
Critical Errors
Cross-reference between Functions and .NET Methods
Cryptographic algorithm test:
Default encoding
Detecting Win32 or X64 platform
Ecc Class
Elliptic Curve Cryptography (ECC)
Elliptic curve cryptography functions
Elliptic curve Diffie-Hellman (ECDH)
Enumerations in .NET
Error Handling and Error Codes
Examples of C code
eXtendable-output functions (XOF)
Filenames with 'International' characters
Find length of byte array
General Class
General functions
General Programming Issues
Getting Started
Hash Class
HASH vs XOF vs MAC vs PRF vs KDF
Hex format for NIST/SEC EC keys
Hmac Class
HMAC Functions
Hpke Class
Hybrid Public Key Encryption (HPKE)
Hybrid Public Key Encryption (HPKE) functions
Index
Installation
Intel(R) DRNG support
Internal key strings
Introduction to CryptoSys PKI Pro
ISO 8601 date-time formats
ISO/IEC 9796-1 Formatting
Kdf Class
Key Derivation Functions
Key Security
Key Storage Format (ECC)
Key Storage Format (RSA)
LDAP String Representation of Distinguished Names
List of .Net Methods
List of Functions
Message Digest Hash Functions
New in this version
Notes on VBA wrapper functions
Ocsp Class
OCSP Functions
Optional Registry Settings
Other Issues For VB6/VBA Users
Padding functions
Padding schemes for block ciphers
Pair-wise consistency test:
Parameters for RSA-PSS and RSA-OAEP available in this Toolkit
Passing a reference to an empty byte array in VB6/VBA
Password prompt functions
Password-based encryption functions
Pbe Class
Pem Class
PEM string alternative for X.509 certificates, RSA and EC keys, etc
PEM/binary file conversion functions
Pfx Class
PFX Functions
Power-up Self-Tests
Pre-dimensioning for VB6
Prf Class
Primary References
Pseudorandom functions (PRF)
Pwd Class
Random Number Generator
Random number generator functions
Raw RSA functions
Raw RSA Techniques
Return Values
Revision History
Rng Class
RNG health test:
RNG Mechanisms
Rsa Class
RSA key functions
RSA signature and encryption schemes: RSA-PSS and RSA-OAEP
RSA2 Signing
S/MIME functions
Safe curves for elliptic cryptography
Security Issues
Security options for encrypted private keys
Self-Tests
Sig Class
SIG functions
Smime Class
Software integrity test:
Specifying an arbitrary RDN in a distinguished name
Specifying Distinguished Names
Specifying the algorithm, mode and padding for generic block cipher functions
Specifying the signature algorithm in a SIG_ function
Summary of .NET Classes
Supported Algorithms
Tdea Class
Technical Details
Techniques to add known security strength to the RNG process
Theory
Triple DES (TDEA/3DES) Functions
Type Conversions
Unsupported algorithms
User-supplied entropy (seeds)
Using in MIME-conformant email messages
Using output in XML documents
Using with .NET: C# and VB.NET
Using with ANSI C
Using With Borland C++
Using with C++ (STL)
Using with Classic Visual Basic VB6 and VBA
Using With MinGW gcc
Using with Python
UTF-8 and Latin-1
UTF-8 encoding in distinguished names
Valid key and block sizes for block cipher algorithms
VB6/C Function Summary
VBA Wrapper Function List
VBA Wrapper Functions
Visual Basic or Visual Basic: VB6 vs VB.NET
Win64 (X64) Platform
Wipe Class
Wipe functions
X.509 certificate functions
X.509 Extensions Parameter
X509 Class
Xof Class
Zero-length byte arrays in VB6/VBA

[Contents] [Index]

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://cryptosys.net>