143 lines
3.2 KiB
Go
143 lines
3.2 KiB
Go
package encrypt
|
|
|
|
import (
|
|
"crypto"
|
|
"crypto/rand"
|
|
"crypto/rsa"
|
|
"crypto/sha1"
|
|
"crypto/x509"
|
|
"encoding/pem"
|
|
"fmt"
|
|
"honoka-chan/config"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
)
|
|
|
|
func RSAGen(bits int) {
|
|
//get current path
|
|
_, currentpath, _, _ := runtime.Caller(0)
|
|
currentpath = filepath.Dir(currentpath)
|
|
|
|
//----------------------------------------------private key
|
|
|
|
// GenerateKey generates an RSA keypair of the given bit size using the
|
|
// random source random (for example, crypto/rand.Reader).
|
|
privateKey, err := rsa.GenerateKey(rand.Reader, bits)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
//serialize privatekey to ASN.1 der by x509.MarshalPKCS8PrivateKey
|
|
x509privatekey, err := x509.MarshalPKCS8PrivateKey(privateKey)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
//encode x509 to pem and save to file
|
|
//1. create privatefile
|
|
privatekeyfile, err := os.Create(config.PrivateKeyPath)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer privatekeyfile.Close()
|
|
//2. new a pem block struct object
|
|
privatekeyblock := pem.Block{
|
|
Type: "PRIVATE KEY",
|
|
Headers: nil,
|
|
Bytes: x509privatekey,
|
|
}
|
|
//3. save to file
|
|
pem.Encode(privatekeyfile, &privatekeyblock)
|
|
|
|
//----------------------------------------------public key
|
|
|
|
//get public key
|
|
publickey := privateKey.PublicKey
|
|
//serialize publickey to ASN.1 der by x509.MarshalPKCS8PublicKey
|
|
x509publickey, _ := x509.MarshalPKIXPublicKey(&publickey)
|
|
|
|
//encode x509 to pem and save to file
|
|
//1. create publickeyfile
|
|
publickeyfile, err := os.Create(config.PublicKeyPath)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer publickeyfile.Close()
|
|
|
|
//2. new a pem block struct object
|
|
publickeyblock := pem.Block{
|
|
Type: "PUBLIC KEY",
|
|
Headers: nil,
|
|
Bytes: x509publickey,
|
|
}
|
|
|
|
//3. save to file
|
|
pem.Encode(publickeyfile, &publickeyblock)
|
|
}
|
|
|
|
func RSAEncrypt(plainText []byte, publickeypath string) ([]byte, error) {
|
|
data, err := os.ReadFile(publickeypath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
block, _ := pem.Decode(data)
|
|
if block == nil {
|
|
return nil, fmt.Errorf("invalid RSA public key PEM")
|
|
}
|
|
parsedKey, err := x509.ParsePKIXPublicKey(block.Bytes)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
publicKey, ok := parsedKey.(*rsa.PublicKey)
|
|
if !ok {
|
|
return nil, fmt.Errorf("PEM does not contain an RSA public key")
|
|
}
|
|
|
|
return rsa.EncryptPKCS1v15(rand.Reader, publicKey, plainText)
|
|
}
|
|
|
|
func RSADecrypt(cipherText []byte) ([]byte, error) {
|
|
privateKey, err := loadPrivateKey()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return rsa.DecryptPKCS1v15(rand.Reader, privateKey, cipherText)
|
|
}
|
|
|
|
func RSASignSHA1(cipherText []byte) ([]byte, error) {
|
|
privateKey, err := loadPrivateKey()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
msgHash := sha1.New()
|
|
_, _ = msgHash.Write(cipherText)
|
|
msgHashSum := msgHash.Sum(nil)
|
|
|
|
return rsa.SignPSS(rand.Reader, privateKey, crypto.SHA1, msgHashSum, nil)
|
|
}
|
|
|
|
func loadPrivateKey() (*rsa.PrivateKey, error) {
|
|
data, err := os.ReadFile(config.PrivateKeyPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
block, _ := pem.Decode(data)
|
|
if block == nil {
|
|
return nil, fmt.Errorf("invalid RSA private key PEM")
|
|
}
|
|
parsedKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
privateKey, ok := parsedKey.(*rsa.PrivateKey)
|
|
if !ok {
|
|
return nil, fmt.Errorf("PEM does not contain an RSA private key")
|
|
}
|
|
return privateKey, nil
|
|
}
|