apple / swift-asn1

An implementation of ASN.1 for Swift
https://swiftpackageindex.com/apple/swift-asn1/main/documentation/swiftasn1
Apache License 2.0
137 stars 27 forks source link

Convert RSA private key in PEM format to OpenSSH format #47

Closed Typ0genius closed 11 months ago

Typ0genius commented 1 year ago

Hello,

I want to convert an RSA private key in PEM format to OpenSSH format. I only got so far in converting the key to an ASN1 object:

import SwiftASN1
import CryptoKit

let key = """
-----BEGIN RSA PRIVATE KEY-----
MIIG4wIBAAKCAYEAnUx+3ufsDbhhsF5bE40YYhZdPI7UDLx6zWaC0Fa7ogEbTOkx
…
arMB2W/9HFE9zPvQbt5Dk0r1XUxnwnKhIQgLkPc67WSFMgEGM9/H
-----END RSA PRIVATE KEY-----
"""
let pemObject = try PEMDocument(pemString: key)
let asn1node = try DER.parse(pemObject.derBytes)

(the key was specifically generated for this example and deleted afterwards)

Is that possible by using this library? If this is the case, can you give me some hints?

Lukasa commented 1 year ago

Generally, yes, you can do this. The RSA private key format here is the PKCS1 format, which is defined in RFC 8017:

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

You can probably expect the version to be two-prime in most cases. This can be decoded using ArraySlice as the bigint type for the integers. You can see examples of how to write ASN1 types in this repo or in the documentation, and hopefully you'll be able to follow along there.

The OpenSSH private key format is a bit trickier, and this library can't help you encode it, though swift-nio-ssh may have the helpers you want. You can see a writeup of the key format here.