1

Consider the fields highlighted in red in the following keys.

  1. Will the "version" fields (i.e. INTEGER 0) always be zero for the specified structure?
  2. Will the NULL fields fields always be NULL for the specified structure?
  3. If "No", what would cause the values to change?

PKCS#1 Private Key: enter image description here

PKCS#8 Private Key: enter image description here

X.509/SPKI Public Key: enter image description here

ubiquibacon
  • 237
  • 1
  • 2
  • 10

2 Answers2

3

Will the "version" fields (i.e. INTEGER 0) always be zero for the specified structure?

As long as one is dealing with standard "biprime" RSA, that is the kind with the public modulus having two distinct primes $p$ and $q$, it's a safe bet one won't meet version other than 0 in a PKCS#1 RSAPrivateKey, including in such structure embedded in a PKCS#8 structure. version 1 is specifically for multiprime RSA, where the modulus can have three or more (distinct) prime factors. There's nothing to prevent using version 1 for biprime RSA, but that's definitely not customary.

From PKCS#1 v2.2; see especially CONSTRAINED BY

RSAPublicKey ::= SEQUENCE {
    modulus            INTEGER,  -- n
    publicExponent     INTEGER   -- e
}

--

-- Representation of RSA private key with information for the CRT algorithm.

RSAPrivateKey ::= SEQUENCE { version Version, modulus INTEGER, -- n publicExponent INTEGER, -- e privateExponent INTEGER, -- d prime1 INTEGER, -- p prime2 INTEGER, -- q exponent1 INTEGER, -- d mod (p-1) exponent2 INTEGER, -- d mod (q-1) coefficient INTEGER, -- (inverse of q) mod p otherPrimeInfos OtherPrimeInfos OPTIONAL }

Version ::= INTEGER { two-prime(0), multi(1) } (CONSTRAINED BY {-- version must be multi if otherPrimeInfos present --})

OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo

OtherPrimeInfo ::= SEQUENCE { prime INTEGER, -- ri exponent INTEGER, -- di coefficient INTEGER -- ti }

The version field of an extended PKCS#8 structure has been assigned the value 1 in a new RFC, see dave_thompson_085's comment, though we have no report of seeing other than 0 in the wild (still, I lost my bet that a whole new structure would be created instead should an extension become desirable).

I'll refrain from commenting the NULL that are following the OIDs, for I fail to track their nature.

Note: when parsing or generating ASN.1 in crypto, there are two choices:

  1. Building a small ad-hoc parser/generator for an ASN.1 DER structure at hand; in this case it's essential to stop parsing as soon as something unexpected is met, or we start to parse outside the input.
  2. Using a full-fledged library. This tends to be a huge and complex piece of software, perhaps with bugs, and even more probably with bugs in how a beginner uses it. However, past a certain degree of complexity, including parsing X.509 certificates of unspecified origin or anything BER, PER or more complex, that's perhaps a necessity.
fgrieu
  • 149,326
  • 13
  • 324
  • 622
1

The NULL fields you ask about are the parameters element of the AlgorithmIdentifier defined in X.509/PKIX e.g. rfc5280 4.1.1.2 -- although it is defined in relation to the signature on the cert or CRL, it is also used for publickeys and privatekeys as you have seen, and quite a lot of other places as well, such as the DigestInfo used in PKCS1v1 signatures, now retronymed RSASSA-PKCS1-v1_5.

For original-style RSA public keys identifed by rsaEncryption in SPKI, rfc3279 2.3.1 (to which you have been referred several times) specifies parameters to be (explicit, see below) NULL. Although TTBOMK there is no comparable rfc for the embedding of RSA private keys in PKCS8, in practice everyone uses the same AlgId -- that is, the same OID and the same parameters.

For RSASSA-PSS signature (added to PKCS1 at v2.1 aka rfc3447), the AlgId must have parameters as shown in rfc4055 3.1. Depending on other specifications, the keys used to generate (private) and verify (public) such signatures can be either original-style RSA keys, or RSA keys restricted to PSS with the OID and optionally params shown in 3279; as it says "parameters may be either absent or present [in SPKI for publickey]". Historically there has been ambiguity and sometimes confusion over whether AlgId's for algorithms with no parameters should use explicit NULL or simply omit the field since it is OPTIONAL in the ASN.1. OpenSSL (at least) takes 'absent' literally and does the latter here for both SPKI and PKCS8, see Create RSA Public/Private Keys with OID rsassaPss ; also see Are RSA-PSS parameters standardized? for some additional discussion on using the parameters and https://stackoverflow.com/questions/42898747/create-private-key-and-certificate-using-rsassa-pss-with-openssl for creating a key with them.

Algorithms other than RSA can also have parameters. Parameters for DSA, DH(X9.42), and ECDSA/ECDH(X9.62/63/SECG) are defined in 3279; ECDSA/ECDH is updated in rfc5480 which (greatly) simplifies ECParameters by keeping only the 'namedCurve OID` variant. OTOH for Bernstein et al's EdDSA and XDH, rfc8410 specifies different OIDs for each curve and absent parameters (explicit in the ASN.1 in section 9).

dave_thompson_085
  • 6,523
  • 1
  • 22
  • 25