Skip to content

Instantly share code, notes, and snippets.

@phpor
Created September 8, 2014 11:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save phpor/9fab17314b985898d508 to your computer and use it in GitHub Desktop.
Save phpor/9fab17314b985898d508 to your computer and use it in GitHub Desktop.
public decrypt in Go
package rsa
import (
"errors"
"math/big"
"crypto/rsa"
"encoding/pem"
"crypto/x509"
)
func PublicDecrypt(pemkey string, enc []byte) ([]byte, error) {
block, _ := pem.Decode([]byte(pemkey))
pubinterface, _ := x509.ParsePKIXPublicKey(block.Bytes)
pubkey := pubinterface.(*rsa.PublicKey)
k := (pubkey.N.BitLen() + 7) / 8
if k != len(enc) {
return nil, errors.New("enc data length error")
}
m := new(big.Int).SetBytes(enc)
if m.Cmp(pubkey.N) > 0 {
return nil, errors.New("enc data too long")
}
m.Exp(m, big.NewInt(int64(pubkey.E)), pubkey.N)
d := leftPad(m.Bytes(), k)
if d[0] != 0 {
return nil, errors.New("data broken, first byte is not zero")
}
if d[1] != 0 && d[1] != 1 {
return nil, errors.New("data is not encrypt by private key")
}
var i = 2
for ; i < len(d); i++ {
if d[i] == 0 {
break
}
}
i++
if i == len(d) {
return nil, nil
}
return d[i:], nil
}
// copy from crypto/rsa/rsa.go
// leftPad returns a new slice of length size. The contents of input are right
// aligned in the new slice.
func leftPad(input []byte, size int) (out []byte) {
n := len(input)
if n > size {
n = size
}
out = make([]byte, size)
copy(out[len(out)-n:], input)
return
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment