Skip to content

Commit

Permalink
new ca
Browse files Browse the repository at this point in the history
  • Loading branch information
AbericYang committed Sep 22, 2019
1 parent f476fba commit 13d6178
Show file tree
Hide file tree
Showing 5 changed files with 227 additions and 19 deletions.
65 changes: 65 additions & 0 deletions ca.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
*
* * Copyright (c) 2019. aberic - All Rights Reserved.
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* * http://www.apache.org/licenses/LICENSE-2.0
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*
*/

package gnomon

import (
"crypto/elliptic"
"crypto/x509"
"io"
)

// CACommon CA工具
type CACommon struct{}

// GenerateRSAPKCS1PrivateKey 生成CA自己的私钥——RSA私钥产生(私钥PKCS1格式)
//
// bits 指定生成位大小
//
// path 指定私钥所在生成目录
//
// fileName 指定私钥的文件名称,如'rootCA.key'
func (ca *CACommon) GenerateRSAPKCS1PrivateKey(bits int, path, fileName string) error {
return CryptoRSA().GeneratePKCS1PriKey(bits, path, fileName)
}

// GenerateRSAPKCS8PrivateKey 生成CA自己的私钥——RSA私钥产生(私钥PKCS8格式)
//
// bits 指定生成位大小
//
// path 指定私钥所在生成目录
//
// fileName 指定私钥的文件名称,如'rootCA.key'
func (ca *CACommon) GenerateRSAPKCS8PrivateKey(bits int, path, fileName string) error {
return CryptoRSA().GeneratePKCS8PriKey(bits, path, fileName)
}

// GenerateECCPrivateKey 生成CA自己的私钥——生成ECC私钥
//
// path 指定私钥所在生成目录
//
// fileName 指定生成的密钥名称,如'rootCA.key'
//
// curve 曲线生成类型,如 crypto.S256()/elliptic.P256()/elliptic.P384()/elliptic.P512()
func (ca *CACommon) GenerateECCPrivateKey(path, fileName string, curve elliptic.Curve) error {
return CryptoECC().GeneratePemPriKey(path, fileName, curve)
}

// GenerateCertificate 生成证书
func (ca *CACommon) GenerateCertificate(rand io.Reader, template *x509.CertificateRequest, priv interface{}) (csr []byte, err error) {
return x509.CreateCertificateRequest(rand, template, priv)
}
90 changes: 90 additions & 0 deletions ca_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
*
* * Copyright (c) 2019. aberic - All Rights Reserved.
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* * http://www.apache.org/licenses/LICENSE-2.0
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*
*/

package gnomon

import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"os"
"path/filepath"
"testing"
)

var (
pathcarsapksc1256 = "./tmp/example/ca/pksc1/256"
//pathcarsapksc1512 = "./tmp/example/ca/pksc1/512"
//pathcarsapksc11024 = "./tmp/example/ca/pksc1/1024"
//pathcarsapksc12048 = "./tmp/example/ca/pksc1/2048"

//pathcarsapksc8256 = "./tmp/example/ca/pksc8/256"
//pathcarsapksc8512 = "./tmp/example/ca/pksc8/512"
//pathcarsapksc81024 = "./tmp/example/ca/pksc8/1024"
//pathcarsapksc82048 = "./tmp/example/ca/pksc8/2048"
//
//pathcaeccpemp224 = "./tmp/example/ca/pemp224"
//pathcaeccpemp256 = "./tmp/example/ca/pemp256"
//pathcaeccpemp384 = "./tmp/example/ca/pemp384"
//pathcaeccpemp521 = "./tmp/example/ca/pemp521"

caPriKeyFileName = "rootCA.key" // ca 私钥
caCertificateFileName = "rootCA.crt" // 根证书文件

fileIO *os.File

priRSAKey *rsa.PrivateKey
//priECCKey *ecdsa.PrivateKey

csrData []byte

errCA error
)

func TestCACommon_GenerateRSAPKCS1PrivateKey(t *testing.T) {
if errCA = CA().GenerateRSAPKCS1PrivateKey(256, pathcarsapksc1256, caPriKeyFileName); nil != errCA {
t.Error(errCA)
}
priRSAKey, errCA = CryptoRSA().LoadPriFP(filepath.Join(pathcarsapksc1256, caPriKeyFileName), CryptoRSA().pksC1())
if errCA != nil {
t.Error(errCA)
}
if csrData, errCA = CA().GenerateCertificate(rand.Reader,
&x509.CertificateRequest{
SignatureAlgorithm: x509.SHA256WithRSA,
Subject: pkix.Name{
Country: []string{"CN"},
Organization: []string{"Gnomon"},
OrganizationalUnit: []string{"GnomonRD"},
Locality: []string{"Beijing"},
Province: []string{"Beijing"},
CommonName: "aberic.cn",
},
},
priRSAKey); nil != errCA {
t.Skip(errCA)
}
if fileIO, errCA = os.OpenFile(filepath.Join(pathcarsapksc1256, caCertificateFileName), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600); nil != errCA {
t.Error(errCA)
}
// 将block的PEM编码写入fileIO
if errCA = pem.Encode(fileIO, &pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csrData}); nil != errCA {
t.Error(errCA)
}
}
12 changes: 12 additions & 0 deletions ecc.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ func (e *ECCCommon) Generate(curve elliptic.Curve) (*ecdsa.PrivateKey, *ecdsa.Pu
//
// path 指定公私钥所在生成目录
//
// priFileName 指定生成的密钥名称
//
// pubFileName 指定生成的密钥名称
//
// curve 曲线生成类型,如 crypto.S256()/elliptic.P256()/elliptic.P384()/elliptic.P512()
func (e *ECCCommon) GenerateKey(path, priFileName, pubFileName string, curve elliptic.Curve) error {
var (
Expand Down Expand Up @@ -96,6 +100,10 @@ func (e *ECCCommon) GenerateKey(path, priFileName, pubFileName string, curve ell
//
// path 指定公私钥所在生成目录
//
// priFileName 指定生成的密钥名称
//
// pubFileName 指定生成的密钥名称
//
// curve 曲线生成类型,如 crypto.S256()/elliptic.P256()/elliptic.P384()/elliptic.P512()
func (e *ECCCommon) GeneratePemKey(path, priFileName, pubFileName string, curve elliptic.Curve) error {
var (
Expand Down Expand Up @@ -126,6 +134,8 @@ func (e *ECCCommon) GeneratePemKey(path, priFileName, pubFileName string, curve
//
// path 指定私钥所在生成目录
//
// priFileName 指定生成的密钥名称
//
// curve 曲线生成类型,如 crypto.S256()/elliptic.P256()/elliptic.P384()/elliptic.P512()
func (e *ECCCommon) GeneratePriKey(path, priFileName string, curve elliptic.Curve) error {
var (
Expand All @@ -152,6 +162,8 @@ func (e *ECCCommon) GeneratePriKey(path, priFileName string, curve elliptic.Curv
//
// path 指定私钥所在生成目录
//
// priFileName 指定生成的密钥名称
//
// curve 曲线生成类型,如 crypto.S256()/elliptic.P256()/elliptic.P384()/elliptic.P512()
func (e *ECCCommon) GeneratePemPriKey(path, priFileName string, curve elliptic.Curve) error {
var (
Expand Down
10 changes: 10 additions & 0 deletions gnomon.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ var (
ac *AESCommon
dc *DESCommon
ecc *ECCCommon
cac *CACommon
lc *LogCommon
scc *ScaleCommon
tc *TimeCommon
Expand All @@ -49,6 +50,7 @@ var (
onceAES sync.Once
onceDES sync.Once
onceECC sync.Once
onceCAC sync.Once
onceLog sync.Once
onceScale sync.Once
onceTime sync.Once
Expand Down Expand Up @@ -150,6 +152,14 @@ func CryptoECC() *ECCCommon {
return ecc
}

// CA CA工具
func CA() *CACommon {
onceCAC.Do(func() {
cac = &CACommon{}
})
return cac
}

// Log 日志工具
func Log() *LogCommon {
onceLog.Do(func() {
Expand Down
69 changes: 50 additions & 19 deletions rsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ func (r *RSACommon) GeneratePKCS8Key(bits int, path, priFileName, pubFileName st
}
// block表示PEM编码的结构
block := &pem.Block{
Type: "RSA PRIVATE KEY",
Type: privateRSAKeyPemType,
Bytes: derStream,
}
defer func() { _ = fileIOPri.Close() }()
Expand All @@ -156,7 +156,7 @@ func (r *RSACommon) GeneratePKCS8Key(bits int, path, priFileName, pubFileName st
return err
}
block = &pem.Block{
Type: "PUBLIC KEY",
Type: publicRSAKeyPemType,
Bytes: derPkiX,
}
defer func() { _ = fileIOPub.Close() }()
Expand Down Expand Up @@ -241,7 +241,7 @@ func (r *RSACommon) GeneratePKCS8PriKey(bits int, path, fileName string) error {
}
// block表示PEM编码的结构
block := &pem.Block{
Type: "RSA PRIVATE KEY",
Type: privateRSAKeyPemType,
Bytes: derStream,
}
defer func() { _ = fileIO.Close() }()
Expand Down Expand Up @@ -270,7 +270,7 @@ func (r *RSACommon) GeneratePubKey(privateKey []byte, path, fileName string, pks
derPkiX []byte
err error
)
pri, err := r.parsePrivateKey(privateKey, pks)
pri, err := r.LoadPri(privateKey, pks)
if err != nil {
return err
}
Expand Down Expand Up @@ -324,7 +324,7 @@ func (r *RSACommon) GeneratePubKeyFP(privateKeyFilePath, path, fileName string,
//
// data 待加密数据
func (r *RSACommon) Encrypt(publicKey, data []byte) ([]byte, error) {
pub, err := r.parsePublicKey(publicKey)
pub, err := r.LoadPub(publicKey)
if nil != err {
return nil, err
}
Expand All @@ -338,11 +338,12 @@ func (r *RSACommon) Encrypt(publicKey, data []byte) ([]byte, error) {
//
// data 待加密数据
func (r *RSACommon) EncryptFP(publicKeyFilePath string, data []byte) ([]byte, error) {
bs, err := ioutil.ReadFile(publicKeyFilePath)
pub, err := r.LoadPubFP(publicKeyFilePath)
if nil != err {
return nil, err
}
return r.Encrypt(bs, data)
//加密
return rsa.EncryptPKCS1v15(rand.Reader, pub, data)
}

// Decrypt 私钥解密
Expand All @@ -353,7 +354,7 @@ func (r *RSACommon) EncryptFP(publicKeyFilePath string, data []byte) ([]byte, er
//
// pks 私钥格式,默认提供PKCS1和PKCS8,通过调用‘CryptoRSA().pksC1()’和‘CryptoRSA().pksC8()’方法赋值
func (r *RSACommon) Decrypt(privateKey, data []byte, pks PKSCType) ([]byte, error) {
pri, err := r.parsePrivateKey(privateKey, pks)
pri, err := r.LoadPri(privateKey, pks)
if err != nil {
return nil, err
}
Expand All @@ -369,11 +370,12 @@ func (r *RSACommon) Decrypt(privateKey, data []byte, pks PKSCType) ([]byte, erro
//
// pks 私钥格式,默认提供PKCS1和PKCS8,通过调用‘CryptoRSA().pksC1()’和‘CryptoRSA().pksC8()’方法赋值
func (r *RSACommon) DecryptFP(privateKeyFilePath string, data []byte, pks PKSCType) ([]byte, error) {
bs, err := ioutil.ReadFile(privateKeyFilePath)
if nil != err {
return bs, err
pri, err := r.LoadPriFP(privateKeyFilePath, pks)
if err != nil {
return nil, err
}
return r.Decrypt(bs, data, pks)
// 解密
return rsa.DecryptPKCS1v15(rand.Reader, pri, data)
}

// Sign 签名:采用sha1算法进行签名并输出为hex格式(私钥PKCS8格式)
Expand All @@ -386,7 +388,7 @@ func (r *RSACommon) DecryptFP(privateKeyFilePath string, data []byte, pks PKSCTy
//
// pks 私钥格式,默认提供PKCS1和PKCS8,通过调用‘CryptoRSA().pksC1()’和‘CryptoRSA().pksC8()’方法赋值
func (r *RSACommon) Sign(privateKey, data []byte, hash crypto.Hash, pks PKSCType) ([]byte, error) {
pri, err := r.parsePrivateKey(privateKey, pks)
pri, err := r.LoadPri(privateKey, pks)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -423,7 +425,7 @@ func (r *RSACommon) SignFP(privateKeyPath string, data []byte, hash crypto.Hash,
//
// hash 算法,如 crypto.SHA1/crypto.SHA256等
func (r *RSACommon) Verify(publicKey, data, signData []byte, hash crypto.Hash) error {
pub, err := r.parsePublicKey(publicKey)
pub, err := r.LoadPub(publicKey)
if nil != err {
return err
}
Expand All @@ -450,11 +452,37 @@ func (r *RSACommon) VerifyFP(publicKeyPath string, data, signData []byte, hash c
return r.Verify(bs, data, signData, hash)
}

// parsePrivateKey 解析私钥
// LoadPriFP 加载私钥
//
// privateKeyFilePath 私钥地址
//
// pks 私钥格式,默认提供PKCS1和PKCS8,通过调用‘CryptoRSA().pksC1()’和‘CryptoRSA().pksC8()’方法赋值
func (r *RSACommon) LoadPriFP(privateKeyFilePath string, pks PKSCType) (*rsa.PrivateKey, error) {
bs, err := ioutil.ReadFile(privateKeyFilePath)
if nil != err {
return nil, err
}
return r.LoadPri(bs, pks)
}

// LoadPubFP 加载公钥
//
// publicKeyFilePath 公钥地址
func (r *RSACommon) LoadPubFP(publicKeyFilePath string) (*rsa.PublicKey, error) {
bs, err := ioutil.ReadFile(publicKeyFilePath)
if nil != err {
return nil, err
}
return r.LoadPub(bs)
}

// LoadPri 解析私钥
//
// privateKey 私钥内容,如取出字符串'priData',则传入'string(priData)'即可
//
// pks 私钥格式,默认提供PKCS1和PKCS8,通过调用‘CryptoRSA().pksC1()’和‘CryptoRSA().pksC8()’方法赋值
func (r *RSACommon) parsePrivateKey(key []byte, pks PKSCType) (*rsa.PrivateKey, error) {
pemData, err := r.pemParse(key, privateRSAKeyPemType)
func (r *RSACommon) LoadPri(privateKey []byte, pks PKSCType) (*rsa.PrivateKey, error) {
pemData, err := r.pemParse(privateKey, privateRSAKeyPemType)
if err != nil {
return nil, err
}
Expand All @@ -470,8 +498,11 @@ func (r *RSACommon) parsePrivateKey(key []byte, pks PKSCType) (*rsa.PrivateKey,
}
}

func (r *RSACommon) parsePublicKey(key []byte) (*rsa.PublicKey, error) {
pemData, err := r.pemParse(key, publicRSAKeyPemType)
// LoadPub 加载公钥
//
// publicKey 公钥内容,如取出字符串'pubData',则传入'string(pubData)'即可
func (r *RSACommon) LoadPub(publicKey []byte) (*rsa.PublicKey, error) {
pemData, err := r.pemParse(publicKey, publicRSAKeyPemType)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 13d6178

Please sign in to comment.