-
Star
(152)
You must be signed in to star a gist -
Fork
(37)
You must be signed in to fork a gist
-
-
Save miguelmota/3ea9286bd1d3c2a985b67cac4ba2130a to your computer and use it in GitHub Desktop.
package ciphers | |
import ( | |
"crypto/rand" | |
"crypto/rsa" | |
"crypto/sha512" | |
"crypto/x509" | |
"encoding/pem" | |
"log" | |
) | |
// GenerateKeyPair generates a new key pair | |
func GenerateKeyPair(bits int) (*rsa.PrivateKey, *rsa.PublicKey) { | |
privkey, err := rsa.GenerateKey(rand.Reader, bits) | |
if err != nil { | |
log.Error(err) | |
} | |
return privkey, &privkey.PublicKey | |
} | |
// PrivateKeyToBytes private key to bytes | |
func PrivateKeyToBytes(priv *rsa.PrivateKey) []byte { | |
privBytes := pem.EncodeToMemory( | |
&pem.Block{ | |
Type: "RSA PRIVATE KEY", | |
Bytes: x509.MarshalPKCS1PrivateKey(priv), | |
}, | |
) | |
return privBytes | |
} | |
// PublicKeyToBytes public key to bytes | |
func PublicKeyToBytes(pub *rsa.PublicKey) []byte { | |
pubASN1, err := x509.MarshalPKIXPublicKey(pub) | |
if err != nil { | |
log.Error(err) | |
} | |
pubBytes := pem.EncodeToMemory(&pem.Block{ | |
Type: "RSA PUBLIC KEY", | |
Bytes: pubASN1, | |
}) | |
return pubBytes | |
} | |
// BytesToPrivateKey bytes to private key | |
func BytesToPrivateKey(priv []byte) *rsa.PrivateKey { | |
block, _ := pem.Decode(priv) | |
enc := x509.IsEncryptedPEMBlock(block) | |
b := block.Bytes | |
var err error | |
if enc { | |
log.Println("is encrypted pem block") | |
b, err = x509.DecryptPEMBlock(block, nil) | |
if err != nil { | |
log.Error(err) | |
} | |
} | |
key, err := x509.ParsePKCS1PrivateKey(b) | |
if err != nil { | |
log.Error(err) | |
} | |
return key | |
} | |
// BytesToPublicKey bytes to public key | |
func BytesToPublicKey(pub []byte) *rsa.PublicKey { | |
block, _ := pem.Decode(pub) | |
enc := x509.IsEncryptedPEMBlock(block) | |
b := block.Bytes | |
var err error | |
if enc { | |
log.Println("is encrypted pem block") | |
b, err = x509.DecryptPEMBlock(block, nil) | |
if err != nil { | |
log.Error(err) | |
} | |
} | |
ifc, err := x509.ParsePKIXPublicKey(b) | |
if err != nil { | |
log.Error(err) | |
} | |
key, ok := ifc.(*rsa.PublicKey) | |
if !ok { | |
log.Error("not ok") | |
} | |
return key | |
} | |
// EncryptWithPublicKey encrypts data with public key | |
func EncryptWithPublicKey(msg []byte, pub *rsa.PublicKey) []byte { | |
hash := sha512.New() | |
ciphertext, err := rsa.EncryptOAEP(hash, rand.Reader, pub, msg, nil) | |
if err != nil { | |
log.Error(err) | |
} | |
return ciphertext | |
} | |
// DecryptWithPrivateKey decrypts data with private key | |
func DecryptWithPrivateKey(ciphertext []byte, priv *rsa.PrivateKey) []byte { | |
hash := sha512.New() | |
plaintext, err := rsa.DecryptOAEP(hash, rand.Reader, priv, ciphertext, nil) | |
if err != nil { | |
log.Error(err) | |
} | |
return plaintext | |
} |
If I put the private and public key string into a flat file and read from there, I always get unable to parse private key: asn1: syntax error: data truncated
while calling BytesToPrivateKey
- x509.ParsePKCS1PrivateKey()
. However, if I just keep them in a variable, it works file. Any reason why would this happen?
pubBytes, err := ioutil.ReadFile("./certs/public.key") // This is fine with Encryption
enc := pkg.Encrypt(msg, pkg.ConvertBytesToPublicKey(pubBytes))
priBytes, err := ioutil.ReadFile("./certs/private.key") // This fails for Dencryption
dec := pkg.Decrypt(enc, pkg.ConvertBytesToPrivateKey(priBytes))
Haven't tested it - (about to) but this site shows import and export of keys
Haven't tested it - (about to) but this site shows import and export of keys
👍 Nice one!
Do note that: x509.IsEncryptedPEMBlock
and x509.DecryptPEMBlock
has both been flagged as insecured by design
.
If you have any secure alternative, I'm in!
Great work! 👍
I created a new gist that works with chunks and replaced deprecated methods: https://gist.github.com/dadencukillia/db8e9d0080b5d44bdafa5190d8c04758
Do note that:
x509.IsEncryptedPEMBlock
andx509.DecryptPEMBlock
has both been flagged asinsecured by design
.
If you have any secure alternative, I'm in!Just remove the -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY------ People are so lazy to read and to understand
lol you cleary don't understand shit.
Do note that:
x509.IsEncryptedPEMBlock
andx509.DecryptPEMBlock
has both been flagged asinsecured by design
.
If you have any secure alternative, I'm in!Just remove the -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY------ People are so lazy to read and to understand
read this, get educated, newbie.
The end result of creating an RSA key is to produce the tuple of numbers
(n,d,e)
. The private key is(n,d)
, and the public key is(n,e)
. Even thoughe
is called "encrypt", andd
is called "decrypt"; that is just a shorthand. More accurately...(n,e)
- public operations ... Verify, Encrypt, because neither of these things require a secret.(n,d)
- private operations ... Sign, Decrypt, because both of these require a secret.And be really careful to note that
e
isn't just "public". It's a small, well-known constant! This is not obvious when you read algebra that explains what RSA does. But somebody needs to tell you whatn
is to use it withe
. Once you have the*big.Int
values of(n,d,e)
, it really is as simple as:It is just a matter of whether you apply e or d first. You can't RSA encrypt anything large, so you usually only encrypt keys, or sign hashes. The values being signed or encrypted need to be smaller than n, because in the end they are taken mod_n.