package rsa
import(
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"encoding/base64"
	"goskeleton/app/global/variable"
	"fmt"
)
func GenerateRSAKeyPair() ([]byte, []byte, error) {
    priKey, err := rsa.GenerateKey(rand.Reader, variable.ConfigYml.GetInt("RSA.keySize"))
    if err != nil {
        return nil, nil, err
    }
    pubKey := &priKey.PublicKey

    // 转换为字节切片
    priASN1 := x509.MarshalPKCS1PrivateKey(priKey)
    priPEM := pem.EncodeToMemory(&pem.Block{
        Type:  "PRIVATE KEY",
        Bytes: priASN1,
    })
    pubASN1, err := x509.MarshalPKIXPublicKey(pubKey)
    if err != nil {
        return nil, nil, err
    }
    pubPEM := pem.EncodeToMemory(&pem.Block{
        Type:  "PUBLIC KEY",
        Bytes: pubASN1,
    })
    return pubPEM, priPEM, nil
}

func DecryptWithPrivateKey(privateKey *rsa.PrivateKey, encryptedPassword []byte) ([]byte, error) {
    decryptedBytes, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, encryptedPassword)
    if err != nil {
        return nil, fmt.Errorf("failed to decrypt password: %v", err)
    }
    return decryptedBytes, nil
}

func DecodeBase64(encodedString string) ([]byte, error) {
    decodedBytes, err := base64.StdEncoding.DecodeString(encodedString)
    if err != nil {
        return nil, fmt.Errorf("failed to decode base64 string: %v", err)
    }
    return decodedBytes, nil
}


func parsePKCS1PrivateKey(block *pem.Block) (*rsa.PrivateKey, error) {
    privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
    if err != nil {
        return nil, fmt.Errorf("failed to parse PKCS1 private key: %v", err)
    }
    return privateKey, nil
}

func parsePKCS8PrivateKey(block *pem.Block) (*rsa.PrivateKey, error) {
    privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
    if err != nil {
        return nil, fmt.Errorf("failed to parse PKCS8 private key: %v", err)
    }
    return privateKey.(*rsa.PrivateKey), nil
}

func ParsePrivateKeyFromPEM(pemKey []byte) (*rsa.PrivateKey, error) {
    block, _ := pem.Decode(pemKey)
    if block == nil {
        return nil, fmt.Errorf("failed to parse PEM block")
    }

    // 尝试解析 PKCS#1 格式
    privateKey, err := parsePKCS1PrivateKey(block)
    if err == nil {
        return privateKey, nil
    }

    // 如果不是 PKCS#1 格式，尝试解析 PKCS#8 格式
    return parsePKCS8PrivateKey(block)
}