Generate Custom Certificate And Key Store
- Add Certificate To Keystore
- Android Generate Keystore
- Generate Custom Certificate And Keystore Information
- Generate Custom Certificate And Keystore Key
Overview
Import a certificate to the Java Keystore You will need to import a certificate to the Java Keystore if: You are not using a SSL certificate that is signed by an authority trusted by Java. Tomcat (Apache/Jakarta) Create a CSR; Installation; Creating a keystore and private key. To create a CSR and private key, you will need a new keystore on your server. We highly recommend creating a new keystore rather than using an existing one. SecureTrust will revoke your certificate so that you can generate a new private key and CSR.
Create a folder to collect all necessary files in. In my case, this was d:cert. Copy the following files to this folder The source.pfx file. The certificate of the root CA of the certificate. The certificate(s) of all intermediate CAs existing in the trust chain of the certificate. How to generate a Certificate Signing Request (CSR) via Java Keystore A CSR is encoded text that contains information about the certificate requester. This information includes, but is not limited to, the publisher name for the certificate (referred to as a “Common Name”), organization name (if applicable), and a contact email for the.
The column encryption feature of SQL Server 2016 requires that the Encrypted Column Encryption Keys (ECEKs) stored on the server be retrieved by the client and then decrypted to Column Encryption Keys (CEKs) in order to access the data stored in encrypted columns. ECEKs are encrypted by Column Master Keys (CMKs), and the security of the CMK is important to the security of column encryption. Thus, the CMK should be stored in a secure location; the purpose of a Column Encryption Keystore Provider is to provide an interface to allow the ODBC driver to access these securely stored CMKs. For users with their own secure storage, the Custom Keystore Provider Interface provides a framework for implementing access to secure storage of the CMK for the ODBC driver, which can then be used to perform CEK encryption and decryption.
Each keystore provider contains and manages one or more CMKs, which are identified by key paths - strings of a format defined by the provider. This, along with the encryption algorithm, also a string defined by the provider, can be used to perform the encryption of a CEK and the decryption of an ECEK. The algorithm, along with the ECEK and the name of the provider, are stored in the database's encryption metadata; see CREATE COLUMN MASTER KEY and CREATE COLUMN ENCRYPTION KEY for more information. Thus, the two fundamental operations of key management are:
where the CEKeystoreProvider_name
is used to identify the specific Column Encryption Keystore Provider (CEKeystoreProvider), and the other arguments are used by the CEKeystoreProvider to encrypt/decrypt the (E)CEK. The name and keypath are provided by the CMK metadata, while the algorithm and ECEK value are provided by the CEK metadata. Multiple keystore providers may be present alongside the default built-in provider(s). Upon performing an operation which requires the CEK, the driver uses the CMK metadata to find the appropriate keystore provider by name, and executes its decryption operation, which can be expressed as:
Although the driver has no need to encrypt CEKs, a key management tool may need to do so in order to implement operations such as CMK creation and rotation; this requires performing the inverse operation:
CEKeyStoreProvider interface
This document describes in detail the CEKeyStoreProvider interface. A keystore provider which implements this interface can be used by the Microsoft ODBC Driver for SQL Server. CEKeyStoreProvider implementers can use this guide to develop custom keystore providers usable by the driver.
A keystore provider library ('provider library') is a dynamic-link library which can be loaded by the ODBC driver, and contains one or more keystore providers. The symbol CEKeystoreProvider
must be exported by a provider library, and be the address of a null-terminated array of pointers to CEKeystoreProvider
structures, one for each keystore provider within the library.
A CEKeystoreProvider
structure defines the entry points of a single keystore provider:
Field Name | Description |
---|---|
Name | The name of the keystore provider. It must not be the same as any other keystore provider previously loaded by the driver or present in this library. Null-terminated, wide-character* string. |
Init | Initialization function. If an initialization function is not required, this field may be null. |
Read | Provider read function. May be null if not required. |
Write | Provider write function. Required if Read is not null. May be null if not required. |
DecryptCEK | ECEK decryption function. This function is the reason for existence of a keystore provider, and must not be null. |
EncryptCEK | CEK encryption function. The driver does not call this function, but it is provided to allow for programmatic access to ECEK creation by key management tools. May be null if not required. |
Free | Termination function. May be null if not required. |
With the exception of Free, the functions in this interface all have a pair of parameters, ctx and onError. The former identifies the context in which the function is called, while the latter is used for reporting errors. See Contexts and Error Handling below for more information.
Placeholder name for a provider-defined initialization function. The driver calls this function once, after a provider has been loaded, but before the first time it needs it to perform ECEK decryption or Read()/Write() requests. Use this function to perform any initialization it needs.
Argument | Description |
---|---|
ctx | [Input] Operation context. |
onError | [Input] Error-reporting function. |
Return Value | Return nonzero to indicate success, or zero to indicate failure. |
Placeholder name for a provider-defined communication function. The driver calls this function when the application requests to read data from a (previously-written-to) provider using the SQL_COPT_SS_CEKEYSTOREDATA connection attribute, allowing the application to read arbitrary data from the provider. See Communicating with Keystore Providers for more information.
Argument | Description |
---|---|
ctx | [Input] Operation context. |
onError | [Input] Error-reporting function. |
data | [Output] Pointer to a buffer in which the provider writes data to be read by the application. This corresponds to the data field of the CEKEYSTOREDATA structure. |
len | [InOut] Pointer to a length value; upon input, this is the maximum length of the data buffer, and the provider shall not write more than *len bytes to it. Upon return, the provider should update *len with the number of bytes actually written. |
Return Value | Return nonzero to indicate success, or zero to indicate failure. |
Placeholder name for a provider-defined communication function. The driver calls this function when the application requests to write data to a provider using the SQL_COPT_SS_CEKEYSTOREDATA connection attribute, allowing the application to write arbitrary data to the provider. See Communicating with Keystore Providers for more information.
Argument | Description |
---|---|
ctx | [Input] Operation context. |
onError | [Input] Error-reporting function. |
data | [Input] Pointer to a buffer containing the data for the provider to read. This corresponds to the data field of the CEKEYSTOREDATA structure. The provider must not read more than len bytes from this buffer. |
len | [Input] The number of bytes available in data. This corresponds to the dataSize field of the CEKEYSTOREDATA structure. |
Return Value | Return nonzero to indicate success, or zero to indicate failure. |
Placeholder name for a provider-defined ECEK decryption function. The driver calls this function to decrypt an ECEK encrypted by a CMK associated with this provider into a CEK.
Argument | Description |
---|---|
ctx | [Input] Operation context. |
onError | [Input] Error-reporting function. |
keyPath | [Input] The value of the KEY_PATH metadata attribute for the CMK referenced by the given ECEK. Null-terminated wide-character* string. This is intended to identify a CMK handled by this provider. |
alg | [Input] The value of the ALGORITHM metadata attribute for the given ECEK. Null-terminated wide-character* string. This is intended to identify the encryption algorithm used to encrypt the given ECEK. |
ecek | [Input] Pointer to the ECEK to be decrypted. |
ecekLen | [Input] Length of the ECEK. |
cekOut | [Output] The provider shall allocate memory for the decrypted ECEK and write its address to the pointer pointed to by cekOut. It must be possible to free this block of memory using the LocalFree (Windows) or free (Linux/Mac) function. If no memory was allocated due to an error or otherwise, the provider shall set *cekOut to a null pointer. |
cekLen | [Output] The provider shall write to the address pointed to by cekLen the length of the decrypted ECEK that it has written to **cekOut. |
Return Value | Return nonzero to indicate success, or zero to indicate failure. |
Placeholder name for a provider-defined CEK encryption function. The driver does not call this function nor expose its functionality through the ODBC interface, but it is provided to allow for programmatic access to ECEK creation by key management tools.
Add Certificate To Keystore
Argument | Description |
---|---|
ctx | [Input] Operation context. |
onError | [Input] Error-reporting function. |
keyPath | [Input] The value of the KEY_PATH metadata attribute for the CMK referenced by the given ECEK. Null-terminated wide-character* string. This is intended to identify a CMK handled by this provider. |
alg | [Input] The value of the ALGORITHM metadata attribute for the given ECEK. Null-terminated wide-character* string. This is intended to identify the encryption algorithm used to encrypt the given ECEK. |
cek | [Input] Pointer to the CEK to be encrypted. |
cekLen | [Input] Length of the CEK. |
ecekOut | [Output] The provider shall allocate memory for the encrypted CEK and write its address to the pointer pointed to by ecekOut. It must be possible to free this block of memory using the LocalFree (Windows) or free (Linux/Mac) function. If no memory was allocated due to an error or otherwise, the provider shall set *ecekOut to a null pointer. |
ecekLen | [Output] The provider shall write to the address pointed to by ecekLen the length of the encrypted CEK that it has written to **ecekOut. |
Return Value | Return nonzero to indicate success, or zero to indicate failure. |
Android Generate Keystore
Placeholder name for a provider-defined termination function. Microsoft office product key generator. The driver may call this function upon normal termination of the process.
Note
Wide-character strings are 2-byte characters (UTF-16) due to how SQL Server stores them.
Error Handling
As errors may occur during a provider's processing, a mechanism is provided to allow it to report errors back to the driver in more specific detail than a boolean success/failure. Many of the functions have a pair of parameters, ctx and onError, which are used together for this purpose in addition to the success/failure return value.
The ctx parameter identifies the context in which a provider operation occurs.
The onError parameter points to an error-reporting function, with the following prototype:
typedef void errFunc(CEKEYSTORECONTEXT *ctx, const wchar_t *msg, ..);
Argument | Description |
---|---|
ctx | [Input] The context to report the error on. |
msg | [Input] The error message to report. Null-terminated wide-character string. To allow parameterized information to be present, this string may contain insert-formatting sequences of the form accepted by the FormatMessage function. Extended functionality may be specified by this parameter as described below. |
.. | [Input] Additional variadic parameters to fit format specifiers in msg, as appropriate. |
Generate Custom Certificate And Keystore Information
To report when an error has occurred, the provider calls onError, supplying the context parameter passed into the provider function by the driver and an error message with optional additional parameters to be formatted in it. The provider may call this function multiple times to post multiple error messages consecutively within one provider-function invocation. For example:
The msg
parameter is ordinarily a wide-character string, but additional extensions are available:
By using one of the special predefined values with the IDS_MSG macro, generic error messages already existing and in a localised form in the driver may be utilized. For example, if a provider fails to allocate memory, the IDS_S1_001
'Memory allocation failure' message can be used:
onError(ctx, IDS_MSG(IDS_S1_001));
For the error to be recognised by the driver, the provider function must return failure. When this is performed in the context of an ODBC operation, the posted errors will become accessible on the connection or statement handle via the standard ODBC diagnostics mechanism (SQLError
, SQLGetDiagRec
, and SQLGetDiagField
).
Context Association
The CEKEYSTORECONTEXT
structure, in addition to providing context for the error callback, can also be used to determine the ODBC context in which a provider operation is executed. This allows a provider to associate data to each of these contexts, e.g. to implement per-connection configuration. For this purpose, the structure contains 3 opaque pointers corresponding to the environment, connection, and statement context:
Field | Description |
---|---|
envCtx | Environment context. |
dbcCtx | Connection context. |
stmtCtx | Statement context. |
Each of these contexts is an opaque value which, while not the same as the corresponding ODBC handle, can be used as a unique identifier for the handle: if handle X is associated with context value Y, then no other environment, connection, or statement handles which exist simultaneously at the same time as X will have a context value of Y, and no other context values will be associated with handle X. If the provider operation being accomplished lacks a particular handle context, (e.g. SQLSetConnectAttr calls to load and configure providers, in which there is no statement handle) the corresponding context value in the structure is null.
Example
Keystore Provider
The following code is an example of a minimal keystore provider implementation.
ODBC Application
The following code is a demo application which uses the keystore provider above. When running it, ensure that the provider library is in the same directory as the application binary, and that the connection string specifies (or specifies a DSN which contains) the ColumnEncryption=Enabled
setting.
See Also
Introduction
Generate Custom Certificate And Keystore Key
This article covers the creation of a new Java keystore using Java keytool.
Process
You can watch the video below for a tutorial.
Or, you can check the step by step guidelines below.
1. Create a new keystore:
Open a command prompt in the same directory as Java keytool; alternatively, you may specify the full path of keytool in your command. Pay close attention to the alias you specify in this command as it will be needed later on.keytool -genkey -alias mydomain -keyalg RSA -keystore KeyStore.jks -keysize 2048
2. Generate a CSR based on the new keystore:keytool -certreq -alias mydomain -keystore KeyStore.jks -file mydomain.csr
Answer each question when prompted. Use the chart below to guide you through the process:
Field | Example |
---|---|
First & Last Name | Domain Name for SSL Certificates Entity Name for Code Signing |
Organizational Unit | Support (Optional, e.g. a department) |
Organization | GMO GlobalSign Inc (Entity's Legal Name) |
City / Locality | Portsmouth (Full City name) |
State / Province | New Hampshire (Full State Name) |
Country Code | US (2 Letter Code) |
Confirm or reject the details by typing 'Yes' or 'No' and pressing Enter
Press Enter to use the same password as the keystore, alternatively specify a separate password and press enter.
You should now have a file called mydomain.csr which can be used to order or reissue a digital certificate from GlobalSign.
3. While the order processes, download the root & intermediate certificates for your order. You can identify the correct root & intermediate certificate based on hash algorithm and product type.
4. Import the root & intermediate certificates into your keystore. Import the root certificate first, followed by the intermediate. Make sure you specify the correct alias of 'root' and 'intermediate' respectively.keytool -import -trustcacerts -alias root -file root.crt -keystore KeyStore.jks
keytool -import -trustcacerts -alias intermediate -file intermediate.crt -keystore KeyStore.jks
5. Download & import your new certificate
Download your new certificate; save it as mydomain.crt.
Use the same alias as the private key so it associates them together. The alias here must match the alias of the private key in the first command.keytool -import -trustcacerts -alias mydomain -file mydomain.crt -keystore KeyStore.jks
The keystore is now complete and can be used for signing code or deploying on a Java based web server depending on the product you ordered.