// Convert string to an RSA private key func Base64ToPriv(s string) (*rsa.PrivateKey, os.Error) { if len(s) == 0 { return nil, nil } if !verifyCRC(s) { return nil, nil } s = s[0 : len(s)-1] enc := base64.StdEncoding pk := rsa.PrivateKey{} buf := make([]byte, 4096) // shoud be big enough src := []byte(s) k := -1 // N if k = firstComma(src); k < 0 { return nil, os.ErrorString("missing delimiter") } n, err := enc.Decode(buf, src[0:k]) if err != nil { return nil, err } pk.N = &big.Int{} pk.N.SetBytes(buf[0:n]) src = src[k+1:] // E if k = firstComma(src); k < 0 { return nil, os.ErrorString("missing delimiter") } n, err = enc.Decode(buf, src[0:k]) if err != nil { return nil, err } pke64, err := bytesToInt64(buf[0:n]) if err != nil { return nil, err } pk.E = int(pke64) src = src[k+1:] // D if k = firstComma(src); k < 0 { return nil, os.ErrorString("missing delimiter") } n, err = enc.Decode(buf, src[0:k]) if err != nil { return nil, err } pk.D = &big.Int{} pk.D.SetBytes(buf[0:n]) src = src[k+1:] // P if k = firstComma(src); k < 0 { return nil, os.ErrorString("missing delimiter") } n, err = enc.Decode(buf, src[0:k]) if err != nil { return nil, err } pk.P = &big.Int{} pk.P.SetBytes(buf[0:n]) src = src[k+1:] // Q n, err = enc.Decode(buf, src) if err != nil { return nil, err } pk.Q = &big.Int{} pk.Q.SetBytes(buf[0:n]) return &pk, nil }
func main() { message := []byte("MODULUS") message_p := []byte("PRIME Pea") pb := make([]byte, 32) pb[0] = 0x80 for i, c := range message { pb[i] |= c >> 7 pb[i+1] |= c << 1 } copy(pb[len(message)+2:], message_p) p, err := PrimeWithPrefix(pb, 512) if err != nil { panic(err) } qb := make([]byte, 33) message_q := []byte("PRIME Queue") qb[0] = 0x80 copy(qb[len(message)+2:], message_q) q, err := PrimeWithPrefix(qb, 512) if err != nil { panic(err) } n := big.NewInt(0) n.Mul(p, q) // To calculate the modulus from the desired private key, we need simply to // invert it modulo (p-1)(q-1) phi_p := big.NewInt(-1) phi_p.Add(phi_p, p) phi_q := big.NewInt(-1) phi_q.Add(phi_q, q) phi := big.NewInt(0) phi.Mul(phi_p, phi_q) d := big.NewInt(0x10001) d.ModInverse(d, phi) private := new(rsa.PrivateKey) private.N = n private.E = 0x10001 private.D = d private.Primes = []*big.Int{p, q} private.Precompute() rfckey := rfc3441PrivateKey{Version: 0, Modulus: n, PublicExponent: 0x10001, PrivateExponent: d, Prime1: p, Prime2: q, Exponent1: private.Precomputed.Dp, Exponent2: private.Precomputed.Dq, Coefficient: private.Precomputed.Qinv} priv_enc, err := asn1.Marshal(rfckey) if err != nil { panic(err) } b := pem.Block{Type: "RSA PRIVATE KEY", Bytes: priv_enc} pem.Encode(os.Stdout, &b) }