Skip to content

Instantly share code, notes, and snippets.

@kkHAIKE
Created April 8, 2018 03:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kkHAIKE/be3b8d7ff8886457c6fdac2714d56fe1 to your computer and use it in GitHub Desktop.
Save kkHAIKE/be3b8d7ff8886457c6fdac2714d56fe1 to your computer and use it in GitHub Desktop.
golang rsa private key encrypt and public key decrypt
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/hex"
"encoding/pem"
"errors"
"fmt"
"io/ioutil"
"math/big"
"os"
)
var (
errPublicModulus = errors.New("crypto/rsa: missing public modulus")
errPublicExponentSmall = errors.New("crypto/rsa: public exponent too small")
errPublicExponentLarge = errors.New("crypto/rsa: public exponent too large")
)
func encrypt_priv(priv *rsa.PrivateKey, c *big.Int) *big.Int {
m := new(big.Int).Exp(c, priv.D, priv.N)
return m
}
func checkPub(pub *rsa.PublicKey) error {
if pub.N == nil {
return errPublicModulus
}
if pub.E < 2 {
return errPublicExponentSmall
}
if pub.E > 1<<31-1 {
return errPublicExponentLarge
}
return nil
}
func copyWithLeftPad(dest, src []byte) {
numPaddingBytes := len(dest) - len(src)
for i := 0; i < numPaddingBytes; i++ {
dest[i] = 0
}
copy(dest[numPaddingBytes:], src)
}
func encryptPKCS1v15_priv( /*rand io.Reader, */ priv *rsa.PrivateKey, msg []byte) ([]byte, error) {
if err := checkPub(&priv.PublicKey); err != nil {
return nil, err
}
k := (priv.N.BitLen() + 7) / 8
if len(msg) > k-11 {
return nil, rsa.ErrMessageTooLong
}
em := make([]byte, k)
em[1] = 1
for i := 2; i < len(em)-len(msg)-1; i++ {
em[i] = 0xff
}
mm := em[len(em)-len(msg):]
/*
em[1] = 2
ps, mm := em[2:len(em)-len(msg)-1], em[len(em)-len(msg):]
err := nonZeroRandomBytes(ps, rand)
if err != nil {
return nil, err
}
*/
em[len(em)-len(msg)-1] = 0
copy(mm, msg)
m := new(big.Int).SetBytes(em)
c := encrypt_priv(priv, m)
copyWithLeftPad(em, c.Bytes())
return em, nil
}
/*
func decrypt_pub(c *big.Int, pub *rsa.PublicKey, m *big.Int) *big.Int {
e := big.NewInt(int64(pub.E))
c.Exp(m, e, pub.N)
return c
}
func nonZeroRandomBytes(s []byte, rand io.Reader) (err error) {
_, err = io.ReadFull(rand, s)
if err != nil {
return
}
for i := 0; i < len(s); i++ {
for s[i] == 0 {
_, err = io.ReadFull(rand, s[i:i+1])
if err != nil {
return
}
s[i] ^= 0x42
}
}
return
}
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
}
func decryptPKCS1v15_pub_(pub *rsa.PublicKey, ciphertext []byte) (valid int, em []byte, index int, err error) {
k := (pub.N.BitLen() + 7) / 8
if k < 11 {
err = rsa.ErrDecryption
return
}
c := new(big.Int).SetBytes(ciphertext)
m := decrypt_pub(new(big.Int), pub, c)
em = leftPad(m.Bytes(), k)
firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
secondByteIsTwo := subtle.ConstantTimeByteEq(em[1], 2)
lookingForIndex := 1
for i := 2; i < len(em); i++ {
equals0 := subtle.ConstantTimeByteEq(em[i], 0)
index = subtle.ConstantTimeSelect(lookingForIndex&equals0, i, index)
lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingForIndex)
}
validPS := subtle.ConstantTimeLessOrEq(2+8, index)
valid = firstByteIsZero & secondByteIsTwo & (^lookingForIndex & 1) & validPS
index = subtle.ConstantTimeSelect(valid, index+1, 0)
return valid, em, index, nil
}
func decryptPKCS1v15_pub(pub *rsa.PublicKey, ciphertext []byte) ([]byte, error) {
if err := checkPub(pub); err != nil {
return nil, err
}
valid, out, index, err := decryptPKCS1v15_pub_(pub, ciphertext)
if err != nil {
return nil, err
}
if valid == 0 {
return nil, rsa.ErrDecryption
}
return out[index:], nil
}
*/
func gen(bit int) {
priv, err := rsa.GenerateKey(rand.Reader, bit)
if err != nil {
fmt.Println(err.Error())
return
}
fp, err := os.Create(fmt.Sprintf("priv%d.txt", bit))
defer fp.Close()
if err != nil {
fmt.Println(err.Error())
return
}
pem.Encode(fp, &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(priv),
})
fp, err = os.Create(fmt.Sprintf("pub%d.txt", bit))
defer fp.Close()
if err != nil {
fmt.Println(err.Error())
return
}
pubASN1, err := x509.MarshalPKIXPublicKey(&priv.PublicKey)
if err != nil {
fmt.Println(err.Error())
return
}
pem.Encode(fp, &pem.Block{
Type: "PUBLIC KEY",
Bytes: pubASN1,
})
}
func main() {
gen(768);
gen(896);
buf, err := ioutil.ReadFile("priv.txt")
if err != nil {
fmt.Println(err.Error())
return
}
block, _ := pem.Decode(buf)
if err != nil {
fmt.Println(err.Error())
return
}
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
fmt.Println(err.Error())
return
}
plain := "fuck you mother"
//encPub, err := rsa.EncryptPKCS1v15(rand.Reader, &priv.PublicKey, []byte(plain))
encPub, err := hex.DecodeString("C28D2255117E1E820E21A9AFC0D3B326DDAF6FE2FD1BA7E9AF9A2C5C213ADAAFBBA885FCCF68249F294054FFAB489A347E995594C7810891D52A7109502CB1FE7A5C5D26BE8BE4FA4EBC297EB0BB6AA55493E9BDEC8B1E089118F237C5DD4984EACDF96E4C4E2BB993B0146E8114D3B572B1EF349FD7C16069F18E3A2B9BDF4D")
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println("enc_pub: " + hex.Dump(encPub))
decPriv, err := rsa.DecryptPKCS1v15(nil, priv, encPub)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println("dec_priv: " + hex.Dump(decPriv))
encPriv, err := encryptPKCS1v15_priv(priv, []byte(plain))
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println("enc_priv: " + hex.Dump(encPriv))
/*decPub, err := decryptPKCS1v15_pub(&priv.PublicKey, encPriv)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println("dec_pub: " + hex.Dump(decPub)) */
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment