-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkey_rsa.go
136 lines (122 loc) · 4.3 KB
/
key_rsa.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package gocrypto
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
)
type RSALength int
const (
RSA1024 RSALength = 1024 // Not recommended for security as it's considered weak and can potentially be broken by modern computational capabilities.
RSA2048 RSALength = 2048 // The minimum recommended size for modern applications. It provides a good balance between security and performance.
RSA3072 RSALength = 3072 // Offers stronger security for scenarios where 2048 bits might not suffice, such as for long-term data protection.
RSA4096 RSALength = 4096 // Extremely secure, but with significantly slower performance. Often used for highly sensitive data.
)
// NewRSAKey generates a new RSA key with the given key size.
func NewRSAKey(length RSALength) (*RSAKey, error) {
key, err := rsa.GenerateKey(rand.Reader, int(length))
if err != nil {
return nil, err
}
return &RSAKey{key}, nil
}
// RSAKey implementation of the Key interface for RSA keys.
type RSAKey struct {
key *rsa.PrivateKey
}
// PrivateKey returns the private key.
func (key *RSAKey) PrivateKey() *rsa.PrivateKey {
return key.key
}
// PrivateKeyBytes returns the private key in PKCS #1 or PKCS #8 format.
// PKCS #1 is not recommended for security as it's considered weak and
// can potentially be broken by modern computational capabilities.
func (key *RSAKey) PrivateKeyBytes(usePKCS8 bool) ([]byte, error) {
if usePKCS8 {
return x509.MarshalPKCS8PrivateKey(key.key)
}
return x509.MarshalPKCS1PrivateKey(key.key), nil
}
// PrivateKeyPEM returns the private key in PKCS #1 or PKCS #8 PEM-encoded format.
// PKCS #1 is not recommended for security as it's considered weak and
// can potentially be broken by modern computational capabilities.
func (key *RSAKey) PrivateKeyPEM(usePKCS8 bool) ([]byte, error) {
if usePKCS8 {
privateKeyPEM, err := x509.MarshalPKCS8PrivateKey(key.key)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(&pem.Block{
Type: "PRIVATE KEY",
Bytes: privateKeyPEM,
}), nil
} else {
privateKeyPEM := x509.MarshalPKCS1PrivateKey(key.key)
return pem.EncodeToMemory(&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: privateKeyPEM,
}), nil
}
}
// PublicKey returns the public key.
func (key *RSAKey) PublicKey() *rsa.PublicKey {
return &key.key.PublicKey
}
// PublicKeyBytes returns the public key in PKIX or PKCS #1 format.
// PKCS #1 is not recommended for security as it's considered weak and
// can potentially be broken by modern computational capabilities.
func (key *RSAKey) PublicKeyBytes(usePKCS8 bool) ([]byte, error) {
if usePKCS8 {
return x509.MarshalPKIXPublicKey(&key.key.PublicKey)
} else {
return x509.MarshalPKCS1PublicKey(&key.key.PublicKey), nil
}
}
// PublicKeyPEM returns the public key in PKIX or PKCS #1 PEM-encoded format.
// PKCS #1 is not recommended for security as it's considered weak and
// can potentially be broken by modern computational capabilities.
func (key *RSAKey) PublicKeyPEM(usePKCS8 bool) ([]byte, error) {
if usePKCS8 {
publicKeyPEM, err := x509.MarshalPKIXPublicKey(&key.key.PublicKey)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(&pem.Block{
Type: "PUBLIC KEY",
Bytes: publicKeyPEM,
}), nil
} else {
publicKeyPEM := x509.MarshalPKCS1PublicKey(&key.key.PublicKey)
return pem.EncodeToMemory(&pem.Block{
Type: "RSA PUBLIC KEY",
Bytes: publicKeyPEM,
}), nil
}
}
// IssueCertificateBytes issue a self-signed certificate in DER format.
func (key *RSAKey) IssueCertificateBytes(subject pkix.Name, algo x509.SignatureAlgorithm, options *x509.Certificate) ([]byte, error) {
// Create a new certificate template
if options == nil {
options = &x509.Certificate{}
}
options.Subject = subject
options.SignatureAlgorithm = algo
// Generate the certificate
certDER, err := x509.CreateCertificate(rand.Reader, options, options, &key.key.PublicKey, key.key)
if err != nil {
return nil, err
}
return certDER, nil
}
// IssueCertificatePEM issue a self-signed certificate in PEM format.
func (key *RSAKey) IssueCertificatePEM(subject pkix.Name, algo x509.SignatureAlgorithm, options *x509.Certificate) ([]byte, error) {
certDER, err := key.IssueCertificateBytes(subject, algo, options)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: certDER,
}), nil
}