Skip to content

Commit

Permalink
优化 OPENSSH
Browse files Browse the repository at this point in the history
  • Loading branch information
deatil committed Jan 12, 2025
1 parent 348d5e8 commit ef4e256
Show file tree
Hide file tree
Showing 19 changed files with 1,554 additions and 4 deletions.
32 changes: 32 additions & 0 deletions cryptobin/ssh/check.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package ecgdsa

import (
"crypto"
"reflect"
)

type publicKeyEqual interface {
Equal(x crypto.PublicKey) bool
}

// 检测公钥私钥是否匹配
func (this SSH) CheckKeyPair() bool {
// 私钥导出的公钥
pubKeyFromPriKey := this.MakePublicKey().publicKey

if pubKeyFromPriKey == nil || this.publicKey == nil {
return false
}

if pubkeyEqual, ok := pubKeyFromPriKey.(publicKeyEqual); ok {
if pubkeyEqual.Equal(this.publicKey) {
return true
}
}

if reflect.DeepEqual(pubKeyFromPriKey, this.publicKey) {
return true
}

return false
}
110 changes: 110 additions & 0 deletions cryptobin/ssh/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package ecgdsa

import (
"errors"
"crypto/rand"
"encoding/pem"

"github.com/deatil/go-cryptobin/ssh"
)

type (
// 配置
Opts = ssh.Opts
)

var (
// get Cipher
GetCipherFromName = ssh.GetCipherFromName

// Default options
DefaultOpts = ssh.DefaultOpts
)

// 生成私钥 pem 数据
func (this SSH) CreatePrivateKey() SSH {
return this.CreateOpensshPrivateKey()
}

// 生成私钥带密码 pem 数据, PKCS1 别名
func (this SSH) CreatePrivateKeyWithPassword(password []byte, opts ...Opts) SSH {
return this.CreateOpensshPrivateKeyWithPassword(password, opts...)
}

// 生成公钥 pem 数据
func (this SSH) CreatePublicKey() SSH {
return this.CreateOpensshPublicKey()
}

// ====================

// 生成私钥 pem 数据
func (this SSH) CreateOpensshPrivateKey() SSH {
if this.privateKey == nil {
err := errors.New("privateKey empty.")
return this.AppendError(err)
}

privateBlock, err := ssh.MarshalOpenSSHPrivateKey(
rand.Reader,
this.privateKey,
this.options.Comment,
)
if err != nil {
return this.AppendError(err)
}

this.keyData = pem.EncodeToMemory(privateBlock)

return this
}

// 生成私钥带密码 pem 数据
func (this SSH) CreateOpensshPrivateKeyWithPassword(password []byte, opts ...Opts) SSH {
if this.privateKey == nil {
err := errors.New("privateKey empty.")
return this.AppendError(err)
}

useOpts := DefaultOpts
if len(opts) > 0 {
useOpts = opts[0]
}

// 生成私钥
privateBlock, err := ssh.MarshalOpenSSHPrivateKeyWithPassword(
rand.Reader,
this.privateKey,
this.options.Comment,
password,
useOpts,
)
if err != nil {
return this.AppendError(err)
}

this.keyData = pem.EncodeToMemory(privateBlock)

return this
}

// 生成公钥 pem 数据
func (this SSH) CreateOpensshPublicKey() SSH {
if this.publicKey == nil {
err := errors.New("publicKey empty.")
return this.AppendError(err)
}

sshPublicKey, err := ssh.NewPublicKey(this.publicKey)
if err != nil {
return this.AppendError(err)
}

if this.options.Comment != "" {
this.keyData = ssh.MarshalAuthorizedKeyWithComment(sshPublicKey, this.options.Comment)
} else {
this.keyData = ssh.MarshalAuthorizedKey(sshPublicKey)
}

return this
}
17 changes: 17 additions & 0 deletions cryptobin/ssh/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package ecgdsa

import (
"github.com/deatil/go-cryptobin/tool/errors"
)

// 添加错误
func (this SSH) AppendError(err ...error) SSH {
this.Errors = append(this.Errors, err...)

return this
}

// 获取错误
func (this SSH) Error() error {
return errors.Join(this.Errors...)
}
221 changes: 221 additions & 0 deletions cryptobin/ssh/from.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
package ecgdsa

import (
"io"
"crypto/rand"
"crypto/rsa"
"crypto/dsa"
"crypto/ecdsa"
"crypto/ed25519"

"github.com/deatil/go-cryptobin/gm/sm2"
"github.com/deatil/go-cryptobin/tool/encoding"
)

// 生成密钥
func (this SSH) GenerateKeyWithSeed(reader io.Reader) SSH {
switch this.options.PublicKeyType {
case KeyTypeRSA:
privateKey, err := rsa.GenerateKey(reader, this.options.Bits)
if err != nil {
return this.AppendError(err)
}

this.privateKey = privateKey
this.publicKey = &privateKey.PublicKey
case KeyTypeDSA:
privateKey := &dsa.PrivateKey{}
dsa.GenerateParameters(&privateKey.Parameters, reader, this.options.ParameterSizes)
dsa.GenerateKey(privateKey, reader)

this.privateKey = privateKey
this.publicKey = &privateKey.PublicKey
case KeyTypeECDSA:
privateKey, err := ecdsa.GenerateKey(this.options.Curve, reader)
if err != nil {
return this.AppendError(err)
}

this.privateKey = privateKey
this.publicKey = &privateKey.PublicKey
case KeyTypeEdDSA:
publicKey, privateKey, err := ed25519.GenerateKey(reader)
if err != nil {
return this.AppendError(err)
}

this.privateKey = privateKey
this.publicKey = publicKey
case KeyTypeSM2:
privateKey, err := sm2.GenerateKey(reader)
if err != nil {
return this.AppendError(err)
}

this.privateKey = privateKey
this.publicKey = &privateKey.PublicKey
}

return this
}

// 使用自定义数据生成密钥对
func GenerateKeyWithSeed(reader io.Reader, options Options) SSH {
return defaultSSH.
WithOptions(options).
GenerateKeyWithSeed(reader)
}

// 生成密钥
func (this SSH) GenerateKey() SSH {
return this.GenerateKeyWithSeed(rand.Reader)
}

// 生成密钥对
func GenerateKey(options Options) SSH {
return defaultSSH.
WithOptions(options).
GenerateKey()
}

// ==========

// 私钥
func (this SSH) FromPrivateKey(key []byte) SSH {
return this.FromOpensshPrivateKey(key)
}

// 私钥
func FromPrivateKey(key []byte) SSH {
return defaultSSH.FromPrivateKey(key)
}

// 私钥带密码
func (this SSH) FromPrivateKeyWithPassword(key []byte, password []byte) SSH {
return this.FromOpensshPrivateKeyWithPassword(key, password)
}

// 私钥带密码
func FromPrivateKeyWithPassword(key []byte, password []byte) SSH {
return defaultSSH.FromPrivateKeyWithPassword(key, password)
}

// 公钥
func (this SSH) FromPublicKey(key []byte) SSH {
return defaultSSH.FromOpensshPublicKey(key)
}

// 公钥
func FromPublicKey(key []byte) SSH {
return defaultSSH.FromPublicKey(key)
}

// ==========

// 私钥
func (this SSH) FromOpensshPrivateKey(key []byte) SSH {
privateKey, comment, err := this.ParseOpensshPrivateKeyFromPEM(key)
if err != nil {
return this.AppendError(err)
}

this.privateKey = privateKey
this.options.Comment = comment

return this
}

// 私钥
func FromOpensshPrivateKey(key []byte) SSH {
return defaultSSH.FromOpensshPrivateKey(key)
}

// 私钥带密码
func (this SSH) FromOpensshPrivateKeyWithPassword(key []byte, password []byte) SSH {
privateKey, comment, err := this.ParseOpensshPrivateKeyFromPEMWithPassword(key, password)
if err != nil {
return this.AppendError(err)
}

this.privateKey = privateKey
this.options.Comment = comment

return this
}

// 私钥
func FromOpensshPrivateKeyWithPassword(key []byte, password []byte) SSH {
return defaultSSH.FromOpensshPrivateKeyWithPassword(key, password)
}

// 公钥
func (this SSH) FromOpensshPublicKey(key []byte) SSH {
publicKey, comment, err := this.ParseOpensshPublicKeyFromPEM(key)
if err != nil {
return this.AppendError(err)
}

this.publicKey = publicKey
this.options.Comment = comment

return this
}

// 公钥
func FromOpensshPublicKey(key []byte) SSH {
return defaultSSH.FromOpensshPublicKey(key)
}

// ==========

// 字节
func (this SSH) FromBytes(data []byte) SSH {
this.data = data

return this
}

// 字节
func FromBytes(data []byte) SSH {
return defaultSSH.FromBytes(data)
}

// 字符
func (this SSH) FromString(data string) SSH {
this.data = []byte(data)

return this
}

// 字符
func FromString(data string) SSH {
return defaultSSH.FromString(data)
}

// Base64
func (this SSH) FromBase64String(data string) SSH {
newData, err := encoding.Base64Decode(data)

this.data = newData

return this.AppendError(err)
}

// Base64
func FromBase64String(data string) SSH {
return defaultSSH.FromBase64String(data)
}

// Hex
func (this SSH) FromHexString(data string) SSH {
newData, err := encoding.HexDecode(data)

this.data = newData

return this.AppendError(err)
}

// Hex
func FromHexString(data string) SSH {
return defaultSSH.FromHexString(data)
}
Loading

0 comments on commit ef4e256

Please sign in to comment.