Files
honoka-chan/pkg/encrypt/rsa.go
T
2026-07-13 08:03:18 +08:00

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
}