0
$\begingroup$

While playing around with creating an RSA public key, and decoding it using a home brew ASN.1 decoder, I ran into the fact that the public key is BITWRAP-ed. BITWRAP seems to be an OpenSSL modifier, and I wonder why it is needed, what the rationale is?

This page describes what BITWRAP is but not why it is needed.

Why can't $n$ and $e$ be encoded in a regular non-BITWRAP-ed ASN.1 sequence?

Below example shows the BITWRAP modifier in an ASN1 definition (copied from OpenSSL docs):

asn1=SEQUENCE:pubkeyinfo

# BITWRAP here
[pubkeyinfo]
algorithm=SEQUENCE:rsa_alg
pubkey=BITWRAP,SEQUENCE:rsapubkey

[rsa_alg]
algorithm=OID:rsaEncryption
parameter=NULL

[rsapubkey]
n=INTEGER:0xBB6FE79432CC6EA2D8F970675A5A87BFBE1AFF0BE63E879F2AFFB93644\
D4D2C6D000430DEC66ABF47829E74B8C5108623A1C0EE8BE217B3AD8D36D5EB4FCA1D9
e=INTEGER:0x010001
$\endgroup$
4
$\begingroup$

That is a Subject Public Key Info structure defined by the X.509 standard:

   SubjectPublicKeyInfo  ::=  SEQUENCE  {
        algorithm            AlgorithmIdentifier,
        subjectPublicKey     BIT STRING  }

The reason it's BITWRAP-ed is that the structure of the wrapped public key depends on the algorithm. It could be a RSA public key as you described, but it could be an elliptic curve or DSA public key too. Without wrapping, the ASN.1 parser would need to be aware of the algorithm it has just parsed to know how to parse the subjectPublicKey, which is cumbersome. With wrapping, it just parses the whole structure and subjectPublicKey can be interpreted later.

(The big question for me it's why it uses a BIT STRING instead of a OCTET STRING...)

$\endgroup$
1
  • 1
    $\begingroup$ My guess on the big question: there could be algorithms which public key is a single component (rather than constructed), and that component's natural type could be an integer, octet string or bitstring depending on algorithm (e.g. bitstring would be a natural choice for the public-key of a cryptosystem based on the DLP problem in $GF(2^{9941})$, which used to make sense). Everyone agrees on how to decode an octet string and its length from a bitstring, and a (big-endian) integer from a bitstring. But various conventions exist to decode a bitstring and its length from the other two. $\endgroup$ – fgrieu Sep 3 '20 at 12:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.