Created
September 8, 2014 11:40
-
-
Save phpor/9fab17314b985898d508 to your computer and use it in GitHub Desktop.
public decrypt in Go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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