Skip to content

Instantly share code, notes, and snippets.

@phemmer
Created September 23, 2015 04:41
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save phemmer/fea012d087ff65819645 to your computer and use it in GitHub Desktop.
Save phemmer/fea012d087ff65819645 to your computer and use it in GitHub Desktop.
xml rsa private key to pem converter in golang
/*
Usage: go run main.go < /path/to/private-key.xml
Optionally takes base64 encoded input.
This is a very crude implementation. Any errors result in a panic.
*/
package main
import (
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"encoding/xml"
"io/ioutil"
"math/big"
"os"
)
func chkErr(err error) {
if err != nil {
panic(err)
}
}
type XMLRSAKey struct {
Modulus string
Exponent string
P string
Q string
DP string
DQ string
InverseQ string
D string
}
func b64d(str string) []byte {
decoded, err := base64.StdEncoding.DecodeString(str)
chkErr(err)
return []byte(decoded)
}
func b64bigint(str string) *big.Int {
bint := &big.Int{}
bint.SetBytes(b64d(str))
return bint
}
func main() {
xmlbs, err := ioutil.ReadAll(os.Stdin)
chkErr(err)
if decoded, err := base64.StdEncoding.DecodeString(string(xmlbs)); err == nil {
xmlbs = decoded
}
xrk := XMLRSAKey{}
chkErr(xml.Unmarshal(xmlbs, &xrk))
key := &rsa.PrivateKey{
PublicKey: rsa.PublicKey{
N: b64bigint(xrk.Modulus),
E: int(b64bigint(xrk.Exponent).Int64()),
},
D: b64bigint(xrk.D),
Primes: []*big.Int{b64bigint(xrk.P), b64bigint(xrk.Q)},
Precomputed: rsa.PrecomputedValues{
Dp: b64bigint(xrk.DP),
Dq: b64bigint(xrk.DQ),
Qinv: b64bigint(xrk.InverseQ),
CRTValues: ([]rsa.CRTValue)(nil),
},
}
pemblock := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)}
chkErr(pem.Encode(os.Stdout, pemblock))
}
@xiaoronglv
Copy link

excellent!

@camyyssa
Copy link

🙏 Worked like a charm! Thank you for sharing this code 🌟

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment