使用Golang解密RSA密钥的方法与实践

使用Golang解密RSA密钥的方法与实践

func main() {
    fmt.Println("hello world")
}

各位同事好,

我需要关于在 Go 语言中解密 RSA 私钥方面的帮助。 我拥有密码短语详情和私钥,我想解密这个私钥。该私钥由第三方使用密码短语加密后,以文件形式分享给了我。

我已经探索了加密库,但我觉得它们可能不适用于我的用例,因为这些密钥是由第三方加密的,并且加密后的密钥是以文件形式分享给我的。 请问有人能建议是否有其他 Go 库/包可以帮助我解密这些私钥吗?

此致, Bhanuprakash

2 回复

或许你可以试试 GitHub - libp2p/go-openssl: Go 语言的 OpenSSL 绑定

package main

import (
	"fmt"
	"os"

	"github.com/libp2p/go-openssl"
)

func main() {

	privateKeyFile := "test_private.pem"
	passPhrase := "thisisawesome"

	encryptedPEM, err := os.ReadFile(privateKeyFile)
	if err != nil {
		panic(err)
	}

	fmt.Print(string(encryptedPEM))

	pvt, err := openssl.LoadPrivateKeyFromPEMWithPassword(encryptedPEM, passPhrase)

	if err != nil {
		panic(err)
	}

	decryptedPEM, err := pvt.MarshalPKCS1PrivateKeyPEM()

	if err != nil {
		panic(err)
	}

	fmt.Print(string(decryptedPEM))

}

为了验证,请使用 openssl 创建一个加密的私钥:

openssl genrsa -aes128 -out test_private.pem 1024

这应该会提示你输入并验证一个密码短语。

现在,使用密码短语解密私钥:

openssl rsa -in test_private.pem -out decrypted_test.pem

decrypted_test.pem 与使用程序解密得到的值进行比较,以检查其是否正常工作。

更多关于使用Golang解密RSA密钥的方法与实践的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中解密RSA私钥,可以使用标准库crypto/x509crypto/rsa。以下是一个完整的示例,展示如何从加密的PEM文件中解密RSA私钥:

package main

import (
    "crypto/rsa"
    "crypto/x509"
    "encoding/pem"
    "fmt"
    "io/ioutil"
)

func main() {
    // 读取加密的私钥文件
    keyFile, err := ioutil.ReadFile("encrypted_private_key.pem")
    if err != nil {
        panic(err)
    }

    // 解码PEM块
    block, _ := pem.Decode(keyFile)
    if block == nil {
        panic("failed to parse PEM block")
    }

    // 检查是否为加密的私钥
    if !x509.IsEncryptedPEMBlock(block) {
        panic("private key is not encrypted")
    }

    // 解密PEM块(密码短语为"your-passphrase")
    decryptedBlock, err := x509.DecryptPEMBlock(block, []byte("your-passphrase"))
    if err != nil {
        panic(err)
    }

    // 解析RSA私钥
    privateKey, err := x509.ParsePKCS1PrivateKey(decryptedBlock)
    if err != nil {
        // 尝试PKCS8格式
        key, err := x509.ParsePKCS8PrivateKey(decryptedBlock)
        if err != nil {
            panic(err)
        }
        privateKey = key.(*rsa.PrivateKey)
    }

    // 使用私钥
    fmt.Printf("Private Key Decrypted: %+v\n", privateKey)
}

如果私钥是PKCS#8格式且使用PBES2加密,可以使用以下方法:

package main

import (
    "crypto/x509"
    "encoding/pem"
    "fmt"
    "io/ioutil"
    "golang.org/x/crypto/pkcs12" // 需要安装:go get golang.org/x/crypto/pkcs12
)

func main() {
    // 读取加密的PKCS#8私钥
    keyFile, err := ioutil.ReadFile("encrypted_pkcs8_key.pem")
    if err != nil {
        panic(err)
    }

    block, _ := pem.Decode(keyFile)
    if block == nil {
        panic("failed to parse PEM block")
    }

    // 使用密码短语解密
    privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes, []byte("your-passphrase"))
    if err != nil {
        panic(err)
    }

    fmt.Printf("PKCS#8 Private Key Decrypted: %T\n", privateKey)
}

对于OpenSSL生成的加密私钥(PKCS#1格式):

package main

import (
    "crypto/x509"
    "encoding/pem"
    "fmt"
    "io/ioutil"
)

func main() {
    // 读取OpenSSL生成的加密私钥
    keyFile, err := ioutil.ReadFile("openssl_encrypted.key")
    if err != nil {
        panic(err)
    }

    block, _ := pem.Decode(keyFile)
    if block == nil {
        panic("failed to parse PEM block")
    }

    // 解密OpenSSL格式的私钥
    decryptedKey, err := x509.DecryptPEMBlock(block, []byte("your-passphrase"))
    if err != nil {
        panic(err)
    }

    privateKey, err := x509.ParsePKCS1PrivateKey(decryptedKey)
    if err != nil {
        panic(err)
    }

    fmt.Printf("OpenSSL Private Key Decrypted: %+v\n", privateKey)
}

如果遇到其他加密格式,可能需要使用专门的库。例如,对于PKCS#12格式(.p12或.pfx文件):

package main

import (
    "crypto/x509"
    "fmt"
    "io/ioutil"
    "golang.org/x/crypto/pkcs12"
)

func main() {
    // 读取PKCS#12文件
    p12Data, err := ioutil.ReadFile("certificate.p12")
    if err != nil {
        panic(err)
    }

    // 解密PKCS#12文件
    privateKey, certificate, err := pkcs12.Decode(p12Data, "your-passphrase")
    if err != nil {
        panic(err)
    }

    fmt.Printf("Private Key: %T\n", privateKey)
    fmt.Printf("Certificate: %v\n", certificate.Subject)
}

确保根据实际的文件格式和加密方式选择合适的解密方法。如果私钥不是PEM格式,可能需要先进行格式转换。

回到顶部