Skip to content

Instantly share code, notes, and snippets.

@zhsj
Last active May 10, 2019 17:45
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 zhsj/c901440b844595bfe96e4c98d6ccc121 to your computer and use it in GitHub Desktop.
Save zhsj/c901440b844595bfe96e4c98d6ccc121 to your computer and use it in GitHub Desktop.
encrypt with RSA private key and decrypt with public key
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/subtle"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"math/big"
)
const (
privateKeyPem = `-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAqByS1otocmp1TNHt+7HU/nNaCtvTZgx8o/Q+95slkZ1ZZOFa
1mD4aFXXU21Io+t5IyuJiv/07lIVCTeidJoFyyhLH7Aj+zIjaCT0MN8UZ9r3qdm2
ObQgs+yIDK+rrFAGzyIZiwmuDsyBO4O7YjrGueItTM8e5T6hT50w5VuizE5AuDD1
t52AWYN/XEgC/ClD7oLHO5LiVHe/bifFM0It0RqbNnUZnZIwl9sGCBADBI0YkaMy
HILh64RU0e+wwm38lNwc7Up7oUk88C06CI1KZxIPEfCI4UwOl2WH7lexwNUbzdkN
2bMjsi+qXxEqmaycnIaRwnRHNrHDGKJl5ORFzQIDAQABAoIBAERbGfnSxa2ATCHo
WnQ1Yv3zuXEg4VxlR2kDL3dOxn/nEypJ173DwD3saZmqnhbI8IC0e0Dhwp4FEjil
PpFa73Aj+ifwXzEMugjmvcQBcTKpfnq547ai34lJbCh8Zbmy8JHYs7otPXEXBpVE
gzT14UhEB1dsAIwGY2ET8YXRNOkNX4bAahXiEMHJpKmcISLECgmoug7slT6o163b
1IWH4ClRAiALuPryZybDwwI+RRQ6IJGWkh08OuOvDD6fCouxjwzOVN4VcWX9lMTo
7TOfAEvC0g3bQaHDPGanhmk5I/mbPtKq/YZVKt8C5gIv+xCa99ardn+RjZUDZp05
5j2O7KECgYEA3RqZ6op506MOYb7uq1arfcfBrqOIGOhD9SCXf1E/HOLy7gHzd1vV
9ywV90dwzLHhudTGa6Cw8MbUuj9USbZ1KOEC6Slg69hWk9HJUp9SXkeU2xxZT+XM
r0Czu/rf4SzEDzW4Gk2OKe9+I+YICDmshz5xg2aJL6vWFG68S5AQE28CgYEAwqTk
RhAMelYi+U7zVLyTF958Mwj0EyvRM+mestk1Wca3vpBeCmgNg/U7s+4vFsn0QhzI
wf1Vqw2wJHiFpEXhXDXpBJyKf5zX90FN052uUbJ6/sUfLo8WQQpDndTicBm5DCc2
i6DefTecCOvzkJPlQdmhph2+PJmHG7aTJPFA7IMCgYEAjHK/XqsD5BnpotGEDjaJ
zOY889BRPXEc6fMACRH1A0Zuhh2bKDCf49iPQ3qP/pboCgFM4UU74FaM/poH0qMi
HQuBq9ZrCKVtqYxTVDZ8PgM+XUjOuuAAezqgcUJVQFYNXJQFFEA7lAvblrYiWAc6
vtY9iPhzIGMJJAWLenxSmeUCgYEAgbeaWgcACde13yh6ihJShSnE484nu08MUOh0
1wRixb3lXp6fzZeiyjp422T1BN76ZcUBFidbHHA231di2SOpGObksCoTMxC37RQc
ZddEATZNOdTs/v5k+lt4zIq/ja3W4P6RH2TKYfDZkCiPXd7yfnwneql/yqsWm6WF
Uq1lczkCgYBujMN7bkufcf92o+yKkIezeVL5UhTXOyuO73okts5cSbfAh8XwFzKc
BsFzTaM/OQEvNJEOV3zRBDqRVr2hhh3g0NA3fOyavcMQJAdzhN93mWhC/usdq7CB
tRkmooPPgbkvYvU0X31Rvmb4pnUAMhIPpGJk4a50jRJaqnx8cOwo9Q==
-----END RSA PRIVATE KEY-----
`
publicKeyPem = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqByS1otocmp1TNHt+7HU
/nNaCtvTZgx8o/Q+95slkZ1ZZOFa1mD4aFXXU21Io+t5IyuJiv/07lIVCTeidJoF
yyhLH7Aj+zIjaCT0MN8UZ9r3qdm2ObQgs+yIDK+rrFAGzyIZiwmuDsyBO4O7YjrG
ueItTM8e5T6hT50w5VuizE5AuDD1t52AWYN/XEgC/ClD7oLHO5LiVHe/bifFM0It
0RqbNnUZnZIwl9sGCBADBI0YkaMyHILh64RU0e+wwm38lNwc7Up7oUk88C06CI1K
ZxIPEfCI4UwOl2WH7lexwNUbzdkN2bMjsi+qXxEqmaycnIaRwnRHNrHDGKJl5ORF
zQIDAQAB
-----END PUBLIC KEY-----
`
message = "hello world!"
)
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 decrypt(pub *rsa.PublicKey, sig []byte) []byte {
k := pub.Size()
m := new(big.Int)
c := new(big.Int).SetBytes(sig)
e := big.NewInt(int64(pub.E))
m.Exp(c, e, pub.N)
em := leftPad(m.Bytes(), k)
firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
secondByteIsTwo := subtle.ConstantTimeByteEq(em[1], 1)
lookingForIndex := 1
index := 0
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 em[index:]
}
func main() {
privateBlock, _ := pem.Decode([]byte(privateKeyPem))
publicBlock, _ := pem.Decode([]byte(publicKeyPem))
privateKey, _ := x509.ParsePKCS1PrivateKey(privateBlock.Bytes)
publicKey, _ := x509.ParsePKIXPublicKey(publicBlock.Bytes)
encryptMsg, _ := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.Hash(0), []byte(message))
fmt.Println("encrypted message:", base64.StdEncoding.EncodeToString(encryptMsg))
decryptMsg := decrypt(publicKey.(*rsa.PublicKey), encryptMsg)
fmt.Println("origin message: ", message)
fmt.Println("decrypted message:", string(decryptMsg))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment