PFX--Personal Information Exchange

The Multi-browser, Multi-platform, Secure Exchange Interoperability Standard for Certificates, CRLs, Private Keys, and Personal Secrets

Discussion Draft V.012

May 31, 1996

Microsoft Corporation

Download Download Microsoft Word (.DOC) format of this document (zipped, 129K).

Note: This is a discussion draft about PFX, which provides a way for clients to transfer personal data from one environment to another without online server intermediaries. As with both SET and STLP, the goal with PFX is to establish a single technology solution (as agreed upon in an open process via an established standards body) to solve an important security need. Microsoft encourages any developer who is interested in this technology to provide comments in the upcoming W3C forums and meetings.

Contents

Overview
Definitions
Security
Prerequisite Standards
Data Model
Protocols
User Interface
Exchange Format
APIs
Acknowledgements
Appendix A
Appendix B

1. Overview

Users of public-key technology have a number of data units that should be characterized as "personal property" because:

Chief among these data units are:

Users must be able to transport this personal property securely--online or offline--from one browser to another and one platform to another.

This information constitutes a user's identity in the public-key infrastructure of the Internet. Our user, Alice, cannot accept having her identity locked into only one machine or one browser make and model. Alice may spend hours at the office getting certificates, keys, and secrets on her office IBM-compatible machine with the "Brand X" browser; but then she needs to take them home--securely--to use on her home Macintosh® with the "Brand Y" browser. She should also be able to take them to a neighbor's house, mall, kiosk, and so on.

Alice's identity belongs to her, not to her machine or her browser. She must be able to access her identity, wherever she may be, to interact with other users and systems on the net. She affirms her identity by signing and decrypting documents with her private keys. She gives evidence of prior authentication of her identity by giving copies of her certificates to requesters. She verifies evidence of others' identities by verifying their certificates. She exercises various minor aspects of her identity by employing assorted personal secrets in various protocols.

We use the term personal information to denote the collection of personal data. The rest of this document describes a machine-independent and browser-independent standard for data formats and APIs to support secure export and import of personal information. A machine-independent data format means that personal information exchange (PFX) data exported from one environment--any type of machine, running any browser--can be imported to any other environment. Standard APIs allow software vendors to write cross-platform applications and browsers easily, expecting the APIs to be available in software libraries on every compliant platform. Browsers should implement the user interface, described herein, that calls the APIs. Other kinds of public-key infrastructure (PKI) applications can also call the APIs.

PFX supports both offline and online transports with well-defined risks and protections in each case. Offline transport is the most secure, because Alice can both algorithmically and physically protect the data. A large number of Web clients use telephone lines and modems, and these are probably at least as painful to the user as taking conscious action to transport data offline. The most secure offline transport is acknowledged to be in hardware tokens such as smart cards. However, it will be years before standards are finalized and cards become ubiquitous. In the meantime, we must do the best we can with software. However, PFX formats will work for either hardware or software transports, so they should be compatible with future hardware security tokens. Online transport allows only algorithmic security, but is most convenient for the user. PFX supports online transport with

2. Definitions

3. Security

3.1. Risks

If an attacker, Mike, intercepts Alice's personal property in transit, Alice will not have the use of it. Worse yet, Mike may impersonate Alice. At the very least, he will gain knowledge of Alice's browsing patterns, her transaction partners and activities, her account numbers, and other secrets. If Mike quietly copies the data, Alice will not know it has been compromised. This is the worst case, because Mike can abuse Alice's identity at the same time Alice uses it. By the time consequences of Mike's actions come back to Alice, she may have suffered irreparable damage to her credit and reputation.

Loss or leakage of private keys is catastrophic, because the potential damage may never be undone. Alice must give keys the utmost protection. Loss or leakage of other confidential data may be discomfiting, so Alice should guard them accordingly. The following table summarizes these risks:

[PFX2385B  3709 bytes ]

3.2. Encryption Modes

How can Alice protect herself? If she can use long-key, public-key encryption, then she has the best protection currently available against hackers opening her safe. She will have reasonable safety for either online or offline transport.

However, she can only use public-key encryption if she has the PFX key-exchange key of the target machine. This may be inconvenient or impossible. It will be inconvenient if she does not happen to have the target key when the need to transport arises. It will be impossible if she does not know the target machine when the need to transport arises; in other words, if she wants the ability to transport to any machine.

Alice can use password-based encryption in these cases. This encryption method converts a password to the same symmetric cipher key at both ends of the transport. In practice, attackers can guess passwords relatively easily. Alice should protect her encrypted safe physically in password mode. In other words, she should avoid online transport, where surreptitious copying is too easy. If she must use it, she is risking exposure and the possible damages listed in the Risks from Exposure table.

We deem the risk of exposure of password-protected private keys to be too great in the online case. Although we cannot prevent Alice from exporting a password-protected PFX safe containing private keys and foolishly transporting it online, we can take the following measures to protect Alice:

Whenever Alice chooses password mode, the user interface should present her with the following admonishments:

There will often be cases where Alice must have online transport and password mode. She must use online transport if either the source or target environments do not support diskettes or she does not have blank diskettes at export time. She must use password mode whenever she does not have the PFX key-exchange key of the target machine.

In these cases, we deem it acceptable to transport all but private keys under password protection. We assume that Mike will only find it economical to steal keys. If he steals certificates and CRLs, he might be able to sell traffic analysis to marketing organizations. However, such information is of low value unless very large numbers of victims are exploited, requiring Mike to mount a very large number of guessing attacks. Even in the worst case, the only risk to Alice is exposure. With the assorted secrets, it seems the worst Mike can do is trigger protocol failures in Alice's transactions. In other words, Mike can harass Alice and her transaction partners. However, the Internet exposes Alice to so many other denial-of-service attacks at all levels that the incremental risk due to PFX seems negligible. See Appendix B for more details of the economic argument.

3.3. Private-Key Generation

If Alice cannot transport her keys in password mode, how can she access them on multiple machines? A straightforward, but unacceptable, solution is for Alice to download her private keys from a server. This is unacceptable because such a server knows Alice's private keys.

Suppose the server only knew some secrets that Alice, and Alice alone, could use to (re)generate her keys. An attacker who learned these secrets would be able to mount dictionary attacks on Alice's user name and password, but could not learn her keys directly. The risk is considerably lower than the server's knowing her keys. This server is a blind oracle: It tells Alice things only it can tell her, but learns nothing about her secrets in the process. The server's purpose is not only to inject unknowns into the process, but to slow down dictionary attacks.

A constraint is that Alice must initially generate any transportable keys with the same process. If Alice will ever use the PFX private-key generation service for a particular key, she must always use it.

She may also have other keys generated locally and securely in the ordinary way, but these can only be transported in PFX public-key mode.

A corollary is that the oracle cannot depend on authenticating Alice to establish a private channel, because Alice may be using the channel to generate keys, before she has any evidence of authentication, such as certificates against the new keys. We can design a simple protocol that never requires client authentication. The following is a sketch:

3.4. Protection Summary

The following table summarizes the protections offered by PFX now and along a foreseeable upgrade arc:

[PFX2385C  4828 bytes ]

4. Prerequisite Standards

PFX uses abstract syntax notation one (ASN.1) for modeling platform independence and private-key cryptographic standards (PKCS) for modeling security. The designers of PFX consider these choices the only practical ones at the time of writing. We would have preferred simpler data modeling techniques such as Secured Transaction Technology's (STT) binary encoding via Cambridge Prefix Notation or Simple Distributed Security Infrastructure's (SDSI's) similar ASCII S-expressions. But neither is sufficiently widely accepted nor implemented to justify choosing it. PKCS has the further disadvantage of being a privately controlled standard. We would have preferred an open or public standard, but there is none presently available, to our knowledge, with the completeness of PKCS.

ASN.1 and PKCS are practical choices because they are widely, if reluctantly, accepted and widely, if imperfectly, implemented at the time of writing.

5. Data Model

The following sections describe syntax and semantics of PFX data.

5.1. Containment Hierarchy

The entity-relationship diagram (Figure 1) illustrates the PFX data model. In prose:

Each environment has one PFX key-exchange key and one PFX safe. The safe has four compartments:

  1. Private keys that are always shrouded.
  2. Certificates and CRLs; while not confidential individually, these reveal private information about Alice's activities and transaction partners. So Alice keeps them in her safe.
    2.1. Personal Certificates that are written against Alice's public keys.
    2.2. Others' Certificates that affirm the identities of other entities.
    2.3. CRLs from all sources; kept together.
  3. Personal secrets such as freshness challenges, blinding factors, message authentication code (MAC) keys, and account numbers.
  4. Extensions so that software written today can accommodate additional compartments defined in the future.
[PFX2385E  4462 bytes ]

Figure 1. Entity-relationship diagram

Data Attributes

5.2.1. The Safe

The safe itself is labeled with its protection mode, either PUBLIC_KEY_MODE or PASSWORD_MODE. It is also labeled with its transport mode, either OFFLINE or ONLINE. The safe must not contain private keys if its protection is PASSWORD_MODE and its transport is ONLINE.

The encryption method is further identified with a PKCS Algorithm Identifier, in the clear. This allows target software to decrypt.

5.2.2. Private keys

Each key has a locally unique nickname in a human-readable string. This nickname is assigned by Alice and must be the same in all her environments. Each key is marked either regenerable or non-regenerable. Each key also points, via thumbprint, to one or more personal certificates that have been written against its corresponding public key. (Thumbprints are defined in the next paragraph.) An exported safe must not contain keys if the transport mode is ONLINE.

5.2.3. Certificates and CRLs

Each certificate or CRL has a category, which is either certificate or CRL. It also has a type, which is X.509, SDSI, or other. Interoperability is not defined for certificates and CRLs of type other. If a type is SDSI, the category must not be CRL. Each has a statistically globally unique thumbprint, which is simply its SHA-1 hash. Each X.509 certificate or CRL also has a globally unique name consisting of an Issuer and a Serial Number.

5.2.4. Personal secrets

Each secret has a locally unique name in a human-readable string. This name is assigned by Alice and must be the same in all her environments.

5.2.5. Extensions

The extension technique is modeled after X.509. Each extension has a globally unique object identifier (OID) of ASN.1 type OBJECT IDENTIFIER, allowing software to dispatch to processing routines if it knows the OID. Each also has a criticality flag; if software does not know the OID and the criticality flag is TRUE, software must abort. Each extension also has a binary value, whose semantics depend on the OID.

6. Protocols

6.1. Public-key Mode

[PFX2385F  7713 bytes ]

Figure 2. Public-key mode

In this mode, Alice takes a diskette containing her home machine's PFX public key-exchange key (PPKEK) to the office in the morning. This key--and its corresponding private key--was generated when Alice installed the PFX system on her home machine. After logging Alice on, the office machine's PFX system allows Alice to encrypt her PFX safe with the PPKEK, creating a PK-Enveloped PDU. Alice can e-mail the PDU home, put it on a server, or take it home on a diskette. This is standard public-key enveloping of Alice's safe, as used in many accepted secure protocols.

More formally, to transport the safe from environment A to environment B, Alice must:

  1. Access the PFX export service on environment A according to the security policies in that environment (usually logon and password authentication).
  2. Input the PPKEK in the form of a self-signed, X.509 certificate with key-usage restriction "PFX".
  3. The PFX export service does the following (this is roughly the process to create a PKCS#7 EnvelopedData):
    3.1. Encodes, that is, streams the PFX safe data into a buffer, X, in a machine-independent format.
    3.2. Generates a fresh, random, bulk-data, symmetric encryption key, K.
    3.3. Encrypts X with key K, resulting in EPFX.
    3.4. Encrypts key K with the PPKEK of environment B, resulting in EK.
    3.5. Packages EPFX and EK into a PFX safe PDU.
  4. Transport the safe PDU, online or offline, to environment B.
  5. Log on to environment B, accessing B's PFX import service, which does the following:
    5.1. Unpacks the safe PDU, yielding EPFX and EK.
    5.2. Decrypts EK, yielding K.
    5.3. Decrypts EPFX with K, yielding a buffer containing the encoded PFX safe data.
    5.4. Decodes the data, that is, transforms it into a convenient, internal representation.
    5.5. Installs the data, following some per-object, common-sense overwrite-confirmation rules explained in section 8, Exchange Format.
6.2. Password Mode

[PFX2385G  9046 bytes ]

Figure 3. Password mode

In this mode, Alice does not need her home machine's PPKEK. She creates and remembers a session password. The office machine's PFX system derives an ordinary, symmetric encryption key from Alice's user name and password and encrypts the PFX plaintext with this key.

We considered the option of folding in entropy from private-key nicknames from the name strings of personal secrets to increase security. This will work if Alice accepts the burden of remembering all these strings and typing them in on the target machine or if the target machine is pre-loaded with these names. We consider both possibilities to be sufficiently remote to reject the idea at present.

Alice's implementation will only save password-encrypted PFX bits to files, and admonishes her not to send the bits home online in this mode, because the system cannot assure the strength of her password. When Alice gets home, she types in the same user name and password, with which the home PFX system decrypts the bits.

More formally, Alice must:

  1. Access the PFX export service on environment A. The PFX export service does the following:
    1.1. Solicits a new PFX password and, optionally, a PFX user name from Alice. The user name may be taken from the system.
    1.2. Solicits a choice of transport mode from Alice.
    1.3. Generates a fresh, random bit string for key-generation salt.
    1.4. Runs the PFX password, the user name, the list of selected private-key nicknames, the name strings of all personal secrets, and the salt through the SHA-1 hash function, producing a new symmetric encryption key, K.
    1.5. Encodes the PFX safe data into a buffer X, omitting private keys if the transport mode is ONLINE_MODE.
    1.6. Encrypts X with key K, resulting in EPFX.
    1.7. Packages the salt and EPFX into a PFX safe PDU.
  2. Transport the safe PDU to environment B.
  3. Log on to environment B, accessing B's PFX import service, which does the following:
    3.1. Unpacks the safe PDU, yielding EPFX and salt.
    3.2. Solicits the PFX password and user name from Alice.
    3.3. Runs the PFX password, the user name, and the salt through a hash function, regenerating K.
    3.4. Decrypts EPFX with K, yielding the encoded PFX safe data.
    3.5. Decodes the data.
    3.6. Installs the data, following per-object, common-sense overwrite-confirmation rules explained in section 8, Exchange Format.
6.3. Private-Key Generation

Alice may select this option on any machine. It will result in the same key material given the same user name, password, and key nickname. The PFX installation has the key-exchange certificate of the key-generation oracle. This option is separate from the export and import options.

[PFX2385H  10842 bytes ]

Figure 4. Private-key generation

More formally:

  1. Preconditions
    1.1. Let H(x) denote a collision-free, one-way hash of the bit string x, namely SHA-1. It is infeasible to find an x and a y such that H(x) = H(y) or to learn x from H(x).
    • Let h be the constant bit length of H(x). For SHA-1, it is 160 (128-bit MD5 is not recommended)

    1.2. Let either x|y or {x, y} denote the concatenation of bit string x and bit string y.
    1.3. Alice's secrets (an attacker stealing these will be able catastrophically to impersonate Alice):
    • u is a bit-string containing Alice's PFX user name. This must be the same in all of Alice's environments.
    • p is a bit-string containing Alice's key (re)generation password. This must be the same in all of Alice's environments. It may (and should be) different from any of Alice's other passwords.
    • n is a nickname Alice applies to a given private key. This allows Alice to regenerate multiple, named sets of private keys in any environment.

    1.4. Let v be the bit length for the private key with nickname n. For signature private keys, a typical length is 1024.
    1.5. The oracle's secrets (an attacker stealing these may be able to act as another oracle and bypass procedural protections against dictionary attacks on Alice's password):
    • Let S be a sequence of permanent, but random numbers, s1, s2, ..., sk, where k = ceil(v/h). There are enough numbers in the sequence to produce hashes that, when concatenated, meet or exceed the bit length, v, of the desired private key. The oracle has enough of these on hand to meet a request for a private key of any reasonable length.

    1.6. Assume a secure channel with an authenticated server between the oracle and Alice.
  2. The protocol
    2.1. Alice sends req = {v, H(u), H(u|p|n)} to the oracle.
    2.2. The oracle saves H(u) for a reasonable time and checks repeated requests against it to stop attackers mounting high-frequency dictionary attacks. A reasonable policy might be to allow five requests per hour on the same H(u). The oracle does not know u, p, or n, so cannot tell whether a request was successful. Only time-based policies seem useful. Someone impersonating the oracle can bypass this policy and permit dictionary attacks.
    2.3. The oracle sends resp = {H(z1), H(z2), ..., H(zk)}, where zi = {H(u|p|n), si}. In other words, the oracle rehashes the hash of Alice's secrets, H(u|p|n), with each of its own secrets. It computes enough of these rehashes to give Alice plenty of bits to generate a long private key.
    2.4. Alice generates her key by a deterministic process from the low-order v bits of {H(w1), H(w2), ..., H(wk)}, where wi = {u, p, n, zi}. In other words, Alice rehashes the oracle's responses with her original secrets, u, p, and n to ensure that an eavesdropper intercepting the responses cannot regenerate her key, because the eavesdropper does not know the secrets. The deterministic process might be, for example, searching for the next higher prime number.

7. User Interface

The following scenario is just an example. This document does not aim to specify user interface in detail.

To take her safe home from the office, Alice performs the following procedure with her "Brand X" browser:

  1. On the File menu, click File\Export Environment....
  2. Set the following controls in the Personal Information Manager dialog box:
    2.1. Select from the radio button group:
    • Password Mode radio button. If Alice selects this and clicks OK in this dialog, she gets the second-level dialog box that states the following: "Please enter a new password to secure the export of your personal information." This dialog box also displays the usual admonitions that the password must be long, difficult to guess, easy to remember, and not written down; but if so, kept separate from the protected data. For example, "Warning! If you forget the password you will not be able to import personal data," and so on.
    • Public-Key Mode radio button. If Alice selects this and clicks OK, she is prompted for a file to open. If Alice brought a floppy with the key in a file called homekey.pfx, she would insert the disk, navigate over to it, and select that file. The system would verify a certificate-like syntax with self-signature on the key and import it to the cryptosystem, in anticipation of using it to envelope.
    • In fact, Alice selects the Public-Key Mode radio button and inserts the right diskette.

    2.2. Review the Private Keys check box. It is grayed if Alice selected Password Mode. If it is not grayed, Alice checks this box.
    • If Alice has more than one private key set, a drop-down list of existing key set nicknames, with all selected, is enabled. Alice can drop this down and press SHIFT or CTRL and click to select or cancel the selection of various nicknames.

    2.3. Review the Certificates & CRLs check box. Alice checks this box.
    2.4. Review the Personal Secrets check box. Alice checks this box.
    • Another drop-down list of secret names, with all selected, is enabled. Alice may press SHIFT or CTRL and click to select or cancel the selection of various secret names.
    • Another application is needed allowing Alice to name secrets and install them in the safe.

    2.5. Select the E-mail or File Transport radio button. The e-mail radio button would be disabled if Alice had selected the Password Mode radion button. Alice chose Public-Key Mode, so she selects the E-mail radio button.
    2.6. Enter e-mail address or filename into text box. Alice enters her own e-mail address, "Alice@bletch.com". She will dial into her mail server from home and pick up the personal information there.
    2.7. Click OK.
All done.

When she gets home, she opens her e-mail and sees a MIME attachment icon containing her personal information. The "Brand Y" browser supports PFX Importation by MIME type, so all she needs to do is double-click on the MIME attachment in the e-mail message. If she had chosen password mode, she would be prompted for the password.

Alice can now use all the data she had at the office at home. Also, if she had any preexisting data at home, it is preserved unless she specifically chose to overwrite it. She can do everything she could do at the office, plus everything she could previously do at home.

8. Exchange Format

ASN.1 and Distinguished Encoding Rules (DER) encoding ensure environment-independence.

Commentary is in-line.

This section is a refinement of the data model in section 5.

First, establish an ASN.1 module named "PFX" and note that its default ASN.1 tags are explicit.

PFX 
DEFINITIONS EXPLICIT TAGS ::= 
BEGIN

Next, import, in the ASN.1 sense, definitions from several standards and export all data types defined in this module.

IMPORTS ContentInfo             FROM PKCS7 pkcs7
        EncryptedPrivateKeyInfo FROM PKCS8 pkcs8
        Name,
        CertificateSerialNumber FROM  X509  x509;

-- EXPORTS All;

The top-level definition is the PersonalInformationExchange. This is the type for personal information in a PKCS#7 ContentInfo whose contentType is either envelopedData or encryptedData.

PersonalInformationExchange ::= ContentInfo

The plaintext is of type SafeContents. It contains a globally unique identifier, pfxOID, registered with an appropriate authority. It will collide with no other OID. Version is an integer that serves to break backwards compatibility: software shall be written to abort if it does not explicitly handle the version in any given instance of this type. Its present value is 1. The remaining four items in the sequence are the meat. CertAndCRLBag, KeyBag, and SecretBag are self-explanatory. Extensions is a well-known technique borrowed from the X.509 certificate standard to support forward and backward compatibility. The IMPLICIT keywords denote optimizations that save a few bytes of tag data.

SafeContents ::= SEQUENCE {
    pfxOID             OBJECT IDENTIFIER -- Value TBD
    version            Version (v1(1)),
    certAndCRLBag      [0] IMPLICIT CertAndCRLBag OPTIONAL,
    keyBag             [1] IMPLICIT KeyBag        OPTIONAL,
    secretBag          [2] IMPLICIT SecretBag     OPTIONAL,
    extensions         [3]          Extensions    OPTIONAL
}

Version ::= INTEGER

A CertCRLBag contains certificates and CRLs. When this specification is finalized, it should be written to contain options for all known standardized certificate formats. For now, it contains an X.509 bag, an LDAP bag, and an SDSI bag; the latter two being just examples.(Please note that several of the links below point to servers that are not under Microsoft's control. Please read Microsoft's official statement regarding other servers.) Information on LDAP can be found at http://ds.internic.net/rfc/rfc1777.txtinternet link. LDAP does not currently define certificates, but most likely will do in its next version. For more information on SDSI, go to http://theory.lcs.mit.edu/~rivest/sdsi.psinternet link and http://theory.lcs.mit.edu/~rivest/internet link.

CertCRLBag ::= SEQUENCE {
    x509Bag   [0] IMPLICIT X509Bag  OPTIONAL,
    ldapBag   [1] IMPLICIT LDAPBag  OPTIONAL -- this is just a sample
    sdsiBag   [2] IMPLICIT SDSIBag  OPTIONAL -- another sample
    -- etc.
}

Each X.509 certificate and CRL is conveniently captured, with some small overhead, in an instance of a PKCS#7 ContentInfo, containing an empty SignedData and a NULL signature. This is explicitly allowed in the standard and is a common idiom. A thumbprint is included in the bag for correlation of the certificate with private keys. The type of the thumbprint is DetachedDigest, another PKCS idiom.

X509Bag ::= SEQUENCE {
    certOrCRL   ContentInfo,
    thumbprint  Thumbprint
}

The following allows the current sample syntax to be complete, though underspecified.

LDAPBag ::= SEQUENCE {
    value      TBD,
    thumbprint Thumbprint
}

SDSIBag ::= SEQUENCE {
    value      TBD,
    thumbprint Thumbprint
}

Thumbprint ::= DetachedDigest
TBD ::= ANY

A KeyBag is a sequence of PKCS#8 PrivateKeyInfos, each associated with

The user interface shall solicit confirmation if Alice attempts to overwrite an existing private key with another one that has the same name. Alice controls her private-key nicknames and they are local to her environments.

KeyBag ::= SEQUENCE OF PrivateKey

PrivateKey ::= SEQUENCE {
    assocCerts  SEQUENCE OF Thumbprints,
    regenerable BOOLEAN DEFAULT FALSE,
    nickname    UniversalString, 
    pkcs8data   PrivateKeyInfo
}

Issue: is UniversalString the right ASN.1 type for a key nickname, or is BMPString better?

Alice's personal secrets are contained in an instance of SecretBag, which, in turn, contains multiple values named with strings Alice assigns. The user interface shall solicit confirmation if Alice attempts to overwrite an existing compartment with another one that has the same name. Compartment names are local to Alice's environments and under the control of her and her application software.

SecretBag ::= SEQUENCE OF Secret

Secret ::= SEQUENCE {
    secretName  UniversalString,
    value       OCTET STRING -- defined by compartment name
}

PFX must allow extensibility. For example, protocol secrets from well known, published protocols like SETinternet link (http://www.visa.com) can be labeled with OIDs and should be part of the safe. Older software must not break when it reads messages containing new objects. It must, at least, ignore data it cannot interpret. The mechanism for intentionally breaking this compatibility is the top-level Version field in the PersonalInformationExchange. Older software is required to report error when reading a PersonalInformationExchange with a version it does not know.

PFX borrows its extensibility mechanism from X.509. An Extension is a sequence of a globally unique extension identifier, assigned by a central authority; a flag indicating criticality, and a value. Software shall parse any extensions present in a PersonalInformationExchange and behave as follows:

-- Modeled after X.509
--
-- If the extnId is known
--     process the extnValue according to published specifications
-- else
--     if "critical" is true
--         error
--     else
--         ignore the extension

Extensions ::= SEQUENCE OF Extension

Extension ::= SEQUENCE {
    extnId       OBJECT IDENTIFIER,
    critical     BOOLEAN DEFAULT FALSE,
    extnValue    OCTET STRING
}

Finally , PFX needs encryption algorithm identifiers. The following are taken from PKCS#1, #5, and SET:

secsig  OBJECT IDENTIFIER ::= {iso(1) identified-organization(3) oiw(14) secsig(3)}
id-sha1 OBJECT IDENTIFIER ::= {secsig 2 26}

--
-- RSA encryption of OAEP'd KEK and SHA1 hash of the "Content", where 
-- the "Content" is defined as with the signature digital operation. 
-- 
rsa1              OBJECT IDENTIFIER ::= {iso(1) member-body(2) us(840) rsadsi(113549)}
pkcs-1            OBJECT IDENTIFIER ::= {rsa1 pkcs(1) 1}
pkcs-5            OBJECT IDENTIFIER ::= {rsa1 pkcs(1) 5}

pbeWithMD5AndDES-CBC  OBJECT IDENTIFIER ::= {pkcs-5  3} -- insecure; do not use
pbeWithSHA1AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 11} -- proposed to RSA
pbeWithSHA1AndRC4     OBJECT IDENTIFIER ::= {pkcs-5 12} -- proposed to RSA

rsaEncryption     OBJECT IDENTIFIER ::= {pkcs-1 1}
rsaOAEPEncryption OBJECT IDENTIFIER ::= {pkcs-1 6}
rsaOAEPEncryptionOfKeySHA1 OBJECT IDENTIFIER ::= {rsaOAEPEncryption 1}
-- missing: contentEncryptionValues for DES-CBC, RC2-CBC, RC4, and CDMF

Note that MD5 has been cryptanalyzed and is no longer secure (private communication). RSA will provide updated algorithm identifiers; we have proposed pbeWithSHA1AndRC2 and pbeWithSHA1AndRC4.

This is the end of the entire PFX module.

END

9. APIs

These APIs cover only import and export. PFX key generation is a separate process not requiring APIs.

9.1. Preliminary, Common Definitions


typedef long int PFXERR;                  // PFX error code 

#define PFXERR_NO_ERROR                        0x00000000
#define PFXERR_WARNING_BUFFER_POINTER_NULL     0x00010001
#define PFXERR_ERROR_INSUFFICIENT_SPACE        0x00020001
#define PFXERR_ERROR_UNKNOWN_MODE              0x00020002
#define PFXERR_ERROR_INVALID_TRANSPORT         0x00020003
#define PFXERR_ERROR_INVALID_PKEK              0x00020004
#define PFXERR_ERROR_PRIVATE_KEY_NOT_FOUND     0x00020005
#define PFXERR_ERROR_UNKNOWN_ALGID             0x00020006
#define PFXERR_ERROR_INVALID_STRING_ARRAYS     0x00020007
#define PFXERR_ERROR_INVALID_HANDLE            0x00020008
#define PFXERR_ERROR_INVALID_INOUT_PARAMETER   0x00020009
#define PFXERR_ERROR_INTERNAL_ERROR            0x0002ffff

typedef unsigned char      BYTE;          // should work on 8-bit byte machines
typedef unsigned short int WORD;          // should work on 32-bit machines
typedef unsigned long int  DWORD;         //   ditto
typedef void*              HANDLE;        // identifies temporary saved state

typedef struct s_PFX                      // Instances contain DER-encoded PFX
{                                         //   (see the ASN.1 definitions, above) 
    BYTE   *pbPFX;                        // Pointer to data buffer
    DWORD   cbPFX;                        // number of bytes needed
} PFX;

typedef struct s_PKEK                     // PFX environment's Public Key-Exchange Key
{
    BYTE   *pbPKEK;                       // Pointer to data buffer
    DWORD   cbPKEK;                       // number of bytes needed
    
} PKEK;

typedef struct s_ALGID                    // PKCS#7 or #5 Algorithm Identifier
{
    BYTE   *pbAlgid;                      // Pointer to data buffer
    DWORD   cbAlgid;                      // number of bytes needed
} ALGID;

#define PFX_PASSWORD_MODE      1
#define PFX_PUBLIC_KEY_MODE    2

#define PFX_ONLINE_TRANSPORT   4
#define PFX_OFFLINE_TRANSPORT  8

typedef struct s_CHARSTRING
{
    BYTE    fUnicode;                     // non-zero if strings are double-byte
    BYTE    fOverwrite;                   // non-zero if Overwriting is desired.
    BYTE   *pbCharString;                 // Pointer to data buffer
    DWORD   cbCharString;                 // number of bytes needed
} CHARSTRING;

typedef struct s_STRARRAY
{
    DWORD        cStrings;                // number of strings in the array
    CHARSTRING  *rgStrings;               // pointer to first string
} STRARRAY;

Implementations bear the responsibility for DER-encoding and decoding the PFX binary.

The following API initializes the entire PFX import and export system, freeing any internal state memory.

    void PFXInit(void);

9.2. Export

To export an entire PersonalInformationExchange data unit from an environment-dependent store into a memory buffer, call this API:

HANDLE PFXExport (
    DWORD  dwProtectionModeInput, 
    DWORD  dwTransportModeInput,
    PKEK  *pPKEKInput, 
    ALGID *pKeyEncryptionAlgidInput, 
    ALGID *pContentEncryptionAlgidInput,
);

If any PFX import / export API ever returns a NULL handle, call

    PFXERR PFXGetLastError(void);

to find the error.

In PFXExport, dwProtectionModeInput must be either PFX_PASSWORD_MODE or PFX_PUBLIC_KEY_MODE. If it is neither, then PFXExport returns a NULL handle and PFXGetLastError returns PFXERR_ERROR_UNKNOWN_MODE.

dwTransportModeInput must be either PFX_ONLINE_TRANSPORT or PFX_OFFLINE_TRANSPORT. If it is neither, then PFXExport returns a NULL handle, and PFXGetLastError returns PFXERR_ERROR_INVALID_TRANSPORT. If it is PFX_ONLINE_TRANSPORT, PFXGetPDU (documented in the code below) will leave the key bag empty.

If dwModeInput is PFX_PUBLIC_KEY_MODE, then pPKEKInput must point to a PKCS#7 ContentInfo with contentType SignedData whose SignerInfos contains a self-signed X.509 certificate that contains the public key-exchange key of the receiving machine. Syntax errors or failure of the signature check results in a NULL handle and PFXGetLastError's returning PFXERR_ERROR_INVALID_PKEK.

If both mode and certificate checks are valid, then the function next examines pAlgidInput. If in password mode, this must point to a DER-encoded OBJECT IDENTIFER value equal to pbeWithSHA1AndRC2-CBC or pbeWithSHA1AndRC4. If in public-key mode, pKeyEncryptionAlgidInput must point to the value rsaOAEPEncryption or rsaOAEPEncryptionOfKeySHA1 and pContentEncryptionAlgidInput must point to the value DES-CBC, CDMF, RC2-CBC, or RC4 (issue: we must get real values for these).

If PFXExport returns a non-NULL handle, pass it to the following API to retrieve the encrypted PFX safe PDU:

 PFXERR PFXGetPDU(HANDLE hPFX, PFX* pPFXPDUOutput);

This API validates the buffer pPFXPDUOutput, and possibly fills it with content, according to the following caller-allocates logic:

Caller-allocates Buffer Management

If pbProvided is NULL, then {

Overwrites cbProvided with cbNeeded (that is, set pPFXPDUOutput->cbPFX = cbNeeded;)

return PFXERR_WARNING_BUFFER_POINTER_NULL

}

Else {

If cbProvided is greater than or equal to cbNeeded {

overwrite the buffer with the data

overwrite cbProvided with the number of bytes actually copied

return PFXERR_NO_ERROR

}

Else {

overwrite the buffer with cbProvided bytes of data, truncating the data transfer

overwrite cbProvided with cbNeeded

return PFXERR_ERROR_INSUFFICIENT_SPACE

}

}

The application may either call PFXGetPDU twice--once to find out the needed size and to allocate a buffer, and the second time to get data--or once, providing a buffer large enough to handle the data in any event. Applications must free allocated space in pPFXPDUOutput after the data has been used.

End of Buffer Management

The contents of pPFXPDUOutput may be written to a disk file or a MIME object for transport. MIME transport should be discouraged in password mode.

When complete, the application should free its own memory and call

    void PFXFreeHandle (HANDLE hPFX);

9.3. Import

To import a package of certs and CRLs from a memory buffer into an environment-dependent store, call the following:

HANDLE PFXImport (
    DWORD    *pdwConfirmOverwrites,
    PKEK     *pPKEKInput, 
    PFX      *pPFXPDUInput
);

The application must provide the self-signed certificate pPKEKInput for import; the function uses this certificate to look up the corresponding private key for decryption. If the certificate is invalid, PFXImport returns a NULL handle and PFXGetLastError returns PFXERR_ERROR_INVALID_PKEK. If the private key cannot be found, PFXImport returns a NULL handle and PFXGetLastError returns PFXERR_ERROR_PRIVATE_KEY_NOT_FOUND.

If pdwConfirmOverwrites is an invalid pointer, then PFXImport returns a NULL handle and PFXGetLastError returns PFXERR_ERROR_INVALID_INOUT_PARAMETER.

If PFXImport returns a valid handle and loads pdwConfirmOverwrites with a non-zero (TRUE) value, call the following API to get arrays of strings to present to the user for confirmation:

PFXERR PFXImportGetConfirmationStrings (
    HANDLE   hPFX,
    STRARRAY *pStrArrayKeysToOverwriteInputOutput,
    STRARRAY *pStrArraySecretsToOverwriteInputOutput
);

This API allocates space for the strings because the handshake between caller and callee would be too complex in a caller-allocates case. If it cannot allocate storage, it will return PFXERR_ERROR_INTERNAL_ERROR.

The CHARSTRINGs in the STRARRAYs will all have FALSE=0 for values of their fOverwrite fields. The application should solicit confirmation from the user for each string in an appropriate user interface, flip the corresponding fOverwrite flag fields for those fields that should be overwritten, and call the following API:

PFXERR PFXImportSetConfirmationStrings (
    HANDLE   hPFX,
    STRARRAY *pStrArrayKeysToOverwriteInput,
    STRARRAY *pStrArraySecretsToOverwriteInput
);

which will deallocate the STRARRAYs and return PFXERR_NO_ERROR in the normal case and PFXERR_ERROR_INTERNAL_ERROR otherwise.

If the application does not call PFXImportSetConfirmationStrings, no overwriting will take place. In any case, the application must call

PFXERR PFXCompleteImportation (
    HANDLE    hPFX,
    DWORD    *pdwModeOutput, 
    ALGID    *pKeyEncryptionAlgidOutput,
    ALGID    *pContentEncryptionAlgidOutput,
)

Because the PFXInput contains a self-describing encrypted data object, the function reports the PFX protection mode and encryption algorithms used in the output parameters dwModeOutput, pKeyEncryptionAlgidOutput, and pContentEncryptionAlgidOutput. If any of these pointers are NULL, the function ignores them. If they are non-null, the function employs a caller-allocation buffer management discipline like that in section 9.2, Export for the algorithm identifiers. The caller may reallocate and retry, at low overhead, as may times as necessary.

When done, the application calls PFXFreeHandle, as with PFXExport.

Applications will need finer control over an environment's certificate store, specifically to add, delete, search on a variety of keys, and to verify. Environment vendors shall supply their own solutions to these problems.

10. Acknowledgments

PFX was designed by Brian Beckman, Terence Spies, and Josh Benaloh. Yacov Yacobi made substantial analytical comments. All are affiliated with Microsoft Corporation.

11. Appendix A: PKCS#5 Encryption

PKCS#8 and #5 explicitly provide encrypted data exchange formats for single private keys. The PFX proposal in password mode extends the symmetric key, password-based methods of PKCS#5 to cover transport of the entire safe, including private keys. Its specific algorithms are a bit dated, but we expect stronger algorithms to be registered with RSADSI in the near future. We are proposing pbeWithSHA1AndRC4 and pbeWithSHA1AndRC2-CBC for inclusion in the next revision.

PKCS#5 encryption is symmetric. The password implies the key. The user provides the password at encryption time and again at decryption time. PKCS#5 and the present standard have no provisions for managing the secret key or the password: that is the user's responsibility. Vendors shall supply prudent user interface or wizards to help users avoid mistakes.

12. Appendix B: Cost of Hacking

Here, we analyze the decision process of an attacker, Mike, who wishes to open a copy of Alice's safe to abuse her secrets. We assume that Mike cannot break a safe protected by public-key encryption; only password-protected safes are even thinkable. Mike will incur a certain expected cost, $C, to break Alice's safe. If Mike's potential gain from abusing Alice's identity is greater than $C, then Mike will do it.

First, we do a concrete analysis with placeholder numbers. We then move to an abstract formula. Assume that, between her user name and password, Alice provides 40 bits of entropy for key generation. This is equivalent to eight characters chosen randomly from a 32-character alphabet. This assumption may be rather generous, becausee Alice will not choose randomly, but from a relatively small dictionary of natural language words with, perhaps, an occasional noise character or gratuitous case change.

The analysis scales linearly with any assumed amount of entropy. In practice, 40 bits is probably the best case; the average case is probably much less, perhaps as little as 30 bits. Continuing with the numbers for 40 bits, Mike will have to do no more than 2^39 trial decryptions, on the average, to open Alice's safe. 2^39 is about 500 billion. At a rate of 1000 decryptions per second, Mike will need 500 million machine-seconds, or about 2 weeks on 500 machines. If a capable machine costs $2,000, then Mike must spend 1 million to start. If he must recover his investment in two years, then he has to make 1 million in 100 weeks, or about $10,000K per week. That translates into $20,000 per breakage.

Because Mike is a crook, he has probably spent much less than $2,000 per machine, so $20,000 is an upper limit to C. Furthermore, because Alice's protection is probably much less than 40 bits, Mike probably breaks her safe much faster, further reducing C. But, even if Mike spends too much, if he can steal private keys, he might be able to forge $20,000 worth of transactions before moving on. It is hard to see how he could recoup $20,000 by stealing only certificates, CRLs and assorted secrets. If his costs were $200--to orders of magnitude less--he might be able to recoup that little.

Algebraically, this little linear analysis is the following:

[PFX2385D  5867 bytes ]

Note that, given a constant amortization time, the cost per safe is independent of the number of machines.

© 1996 Microsoft Corporation