add rsaencode by private key and rsadecode by publickey functions

master v0.0.2
兔子 2 years ago
parent cc7d7b6bd4
commit d6fb0b8c7f

@ -0,0 +1,368 @@
package starcrypto
import (
"encoding/ascii85"
"encoding/base64"
"errors"
"io"
"os"
)
var (
// ErrLength is returned from the Decode* methods if the input has an
// impossible length.
ErrLength = errors.New("base128: invalid length base128 string")
// ErrBit is returned from the Decode* methods if the input has a byte with
// the high-bit set (e.g. 0x80). This will never be the case for strings
// produced from the Encode* methods in this package.
ErrBit = errors.New("base128: high bit set in base128 string")
)
// Encoding table holds all the characters for base91 encoding
var enctab = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~'")
// Decoding table maps all the characters back to their integer values
var dectab = map[byte]byte{
'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7,
'I': 8, 'J': 9, 'K': 10, 'L': 11, 'M': 12, 'N': 13, 'O': 14, 'P': 15,
'Q': 16, 'R': 17, 'S': 18, 'T': 19, 'U': 20, 'V': 21, 'W': 22, 'X': 23,
'Y': 24, 'Z': 25, 'a': 26, 'b': 27, 'c': 28, 'd': 29, 'e': 30, 'f': 31,
'g': 32, 'h': 33, 'i': 34, 'j': 35, 'k': 36, 'l': 37, 'm': 38, 'n': 39,
'o': 40, 'p': 41, 'q': 42, 'r': 43, 's': 44, 't': 45, 'u': 46, 'v': 47,
'w': 48, 'x': 49, 'y': 50, 'z': 51, '0': 52, '1': 53, '2': 54, '3': 55,
'4': 56, '5': 57, '6': 58, '7': 59, '8': 60, '9': 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,
}
// Base91EncodeToString encodes the given byte array and returns a string
func Base91EncodeToString(d []byte) string {
return string(Base91Encode(d))
}
// Base91Encode returns the base91 encoded string
func Base91Encode(d []byte) []byte {
var n, b uint
var o []byte
for i := 0; i < len(d); i++ {
b |= uint(d[i]) << n
n += 8
if n > 13 {
v := b & 8191
if v > 88 {
b >>= 13
n -= 13
} else {
v = b & 16383
b >>= 14
n -= 14
}
o = append(o, enctab[v%91], enctab[v/91])
}
}
if n > 0 {
o = append(o, enctab[b%91])
if n > 7 || b > 90 {
o = append(o, enctab[b/91])
}
}
return o
}
// Base91DecodeToString decodes a given byte array are returns a string
func Base91DecodeString(d string) []byte {
return Base91Decode([]byte(d))
}
// Base91Decode decodes a base91 encoded string and returns the result
func Base91Decode(d []byte) []byte {
var b, n uint
var o []byte
v := -1
for i := 0; i < len(d); i++ {
c, ok := dectab[d[i]]
if !ok {
continue
}
if v < 0 {
v = int(c)
} else {
v += int(c) * 91
b |= uint(v) << n
if v&8191 > 88 {
n += 13
} else {
n += 14
}
o = append(o, byte(b&255))
b >>= 8
n -= 8
for n > 7 {
o = append(o, byte(b&255))
b >>= 8
n -= 8
}
v = -1
}
}
if v+1 > 0 {
o = append(o, byte((b|uint(v)<<n)&255))
}
return o
}
// Base128Encode encodes src into EncodedLen(len(src)) bytes of dst. As a convenience,
// it returns the number of bytes written to dst, but this value is always
// EncodedLen(len(src)).
//
// Encode implements base128 encoding.
func Base128Encode(dst, src []byte) int {
ret := Base128EncodedLen(len(src))
if len(dst) < ret {
panic("dst has insufficient length")
}
dst = dst[:0]
whichByte := uint(1)
bufByte := byte(0)
for _, v := range src {
dst = append(dst, bufByte|(v>>whichByte))
bufByte = (v&(1<<whichByte) - 1) << (7 - whichByte)
if whichByte == 7 {
dst = append(dst, bufByte)
bufByte = 0
whichByte = 0
}
whichByte++
}
dst = append(dst, bufByte)
return ret
}
// Base128Decode decodes src into DecodedLen(len(src)) bytes, returning the actual
// number of bytes written to dst.
//
// If Decode encounters invalid input, it returns an error describing the
// failure.
func Base128Decode(dst, src []byte) (int, error) {
dLen := Base128DecodedLen(len(src))
if Base128EncodedLen(dLen) != len(src) {
return 0, ErrLength
}
if len(dst) < dLen {
panic("dst has insufficient length")
}
dst = dst[:0]
whichByte := uint(1)
bufByte := byte(0)
for _, v := range src {
if (v & 0x80) != 0 {
return len(dst), ErrBit
}
if whichByte > 1 {
dst = append(dst, bufByte|(v>>(8-whichByte)))
}
bufByte = v << whichByte
if whichByte == 8 {
whichByte = 0
}
whichByte++
}
return len(dst), nil
}
// Base128DecodeString returns the bytes represented by the base128 string s.
func Base128DecodeString(s string) ([]byte, error) {
src := []byte(s)
dst := make([]byte, Base128DecodedLen(len(src)))
if _, err := Base128Decode(dst, src); err != nil {
return nil, err
}
return dst, nil
}
// Base128DecodedLen returns the number of bytes `encLen` encoded bytes decodes to.
func Base128DecodedLen(encLen int) int {
return (encLen * 7 / 8)
}
// Base128EncodedLen returns the number of bytes that `dataLen` bytes will encode to.
func Base128EncodedLen(dataLen int) int {
return (((dataLen * 8) + 6) / 7)
}
// Base128EncodeToString returns the base128 encoding of src.
func Base128EncodeToString(src []byte) string {
dst := make([]byte, Base128EncodedLen(len(src)))
Base128Encode(dst, src)
return string(dst)
}
// Base64Encode 输出格式化后的Base64字符串
func Base64Encode(bstr []byte) string {
return base64.StdEncoding.EncodeToString(bstr)
}
// Base64Decode 输出解密前的Base64数据
func Base64Decode(str string) ([]byte, error) {
return base64.StdEncoding.DecodeString(str)
}
// Base85Encode 输出格式化后的Base85字符串
func Base85Encode(bstr []byte) string {
var rtn []byte
rtn = make([]byte, ascii85.MaxEncodedLen(len(bstr)))
ascii85.Encode(rtn, bstr)
return string(rtn)
}
// Base85Decode 输出解密前的Base85数据
func Base85Decode(str string) ([]byte, error) {
var rtn []byte
rtn = make([]byte, len(str))
_, _, err := ascii85.Decode(rtn, []byte(str), true)
return rtn, err
}
// Base85EncodeFile 用base85方法编码src文件到dst文件中去shell传入当前进度
func Base85EncodeFile(src, dst string, shell func(float64)) error {
fpsrc, err := os.Open(src)
if err != nil {
return err
}
defer fpsrc.Close()
stat, _ := os.Stat(src)
filebig := float64(stat.Size())
var sum int64
fpdst, err := os.Create(dst)
if err != nil {
return err
}
defer fpdst.Close()
b85 := ascii85.NewEncoder(fpdst)
defer b85.Close()
for {
buf := make([]byte, 1024000)
n, err := fpsrc.Read(buf)
if err != nil {
if err == io.EOF {
break
}
return err
}
sum += int64(n)
go shell(float64(sum) / filebig * 100)
b85.Write(buf[0:n])
}
return nil
}
// Base85DecodeFile 用base85方法解码src文件到dst文件中去shell传入当前进度
func Base85DecodeFile(src, dst string, shell func(float64)) error {
fpsrc, err := os.Open(src)
if err != nil {
return err
}
defer fpsrc.Close()
stat, _ := os.Stat(src)
filebig := float64(stat.Size())
var sum int64
defer fpsrc.Close()
fpdst, err := os.Create(dst)
if err != nil {
return err
}
defer fpdst.Close()
b85 := ascii85.NewDecoder(fpsrc)
for {
buf := make([]byte, 1280000)
n, err := b85.Read(buf)
if err != nil {
if err == io.EOF {
break
}
return err
}
sum += int64(n)
per := float64(sum) / filebig * 100 / 4.0 * 5.0
if per >= 100 {
per = 100
}
go shell(per)
fpdst.Write(buf[0:n])
}
return nil
}
// Base64EncodeFile 用base64方法编码src文件到dst文件中去shell传入当前进度
func Base64EncodeFile(src, dst string, shell func(float64)) error {
fpsrc, err := os.Open(src)
if err != nil {
return err
}
defer fpsrc.Close()
stat, _ := os.Stat(src)
filebig := float64(stat.Size())
var sum int64 = 0
fpdst, err := os.Create(dst)
if err != nil {
return err
}
defer fpdst.Close()
b64 := base64.NewEncoder(base64.StdEncoding, fpdst)
defer b64.Close()
for {
buf := make([]byte, 1048575)
n, err := fpsrc.Read(buf)
if err != nil {
if err == io.EOF {
break
}
return err
}
sum += int64(n)
go shell(float64(sum) / filebig * 100)
b64.Write(buf[0:n])
}
return nil
}
// Base64DecodeFile 用base64方法解码src文件到dst文件中去shell传入当前进度
func Base64DecodeFile(src, dst string, shell func(float64)) error {
fpsrc, err := os.Open(src)
if err != nil {
return err
}
defer fpsrc.Close()
stat, _ := os.Stat(src)
filebig := float64(stat.Size())
var sum int64 = 0
defer fpsrc.Close()
fpdst, err := os.Create(dst)
if err != nil {
return err
}
defer fpdst.Close()
b64 := base64.NewDecoder(base64.StdEncoding, fpsrc)
for {
buf := make([]byte, 1048576)
n, err := b64.Read(buf)
if err != nil {
if err == io.EOF {
break
}
return err
}
sum += int64(n)
per := float64(sum) / filebig * 100 / 3.0 * 4.0
if per >= 100 {
per = 100
}
go shell(per)
fpdst.Write(buf[0:n])
}
return nil
}

@ -0,0 +1,25 @@
package starcrypto
import (
"fmt"
"testing"
)
func TestRsaCrypt(t *testing.T) {
privKey, pubKey, err := GenerateKey(2048)
if err != nil {
panic(err)
}
data, err := RSAEncryptByPrivkey(privKey, []byte("hello world"))
if err != nil {
t.Fatal(err)
}
code, err := RSADecryptByPubkey(pubKey, data)
if err != nil {
t.Fatal(err)
}
fmt.Println(string(code))
if string(code) != "hello world" {
t.Fail()
}
}

@ -2,21 +2,15 @@ package starcrypto
import (
"bufio"
"crypto"
"crypto/aes"
"crypto/cipher"
"crypto/md5"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"crypto/x509"
"encoding/ascii85"
"encoding/base64"
"encoding/binary"
"encoding/hex"
"encoding/pem"
"errors"
"fmt"
"hash"
@ -30,229 +24,8 @@ import (
"strconv"
"strings"
"time"
"golang.org/x/crypto/ssh"
)
var (
// ErrLength is returned from the Decode* methods if the input has an
// impossible length.
ErrLength = errors.New("base128: invalid length base128 string")
// ErrBit is returned from the Decode* methods if the input has a byte with
// the high-bit set (e.g. 0x80). This will never be the case for strings
// produced from the Encode* methods in this package.
ErrBit = errors.New("base128: high bit set in base128 string")
)
// Encoding table holds all the characters for base91 encoding
var enctab = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~'")
// Decoding table maps all the characters back to their integer values
var dectab = map[byte]byte{
'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7,
'I': 8, 'J': 9, 'K': 10, 'L': 11, 'M': 12, 'N': 13, 'O': 14, 'P': 15,
'Q': 16, 'R': 17, 'S': 18, 'T': 19, 'U': 20, 'V': 21, 'W': 22, 'X': 23,
'Y': 24, 'Z': 25, 'a': 26, 'b': 27, 'c': 28, 'd': 29, 'e': 30, 'f': 31,
'g': 32, 'h': 33, 'i': 34, 'j': 35, 'k': 36, 'l': 37, 'm': 38, 'n': 39,
'o': 40, 'p': 41, 'q': 42, 'r': 43, 's': 44, 't': 45, 'u': 46, 'v': 47,
'w': 48, 'x': 49, 'y': 50, 'z': 51, '0': 52, '1': 53, '2': 54, '3': 55,
'4': 56, '5': 57, '6': 58, '7': 59, '8': 60, '9': 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,
}
// Base91EncodeToString encodes the given byte array and returns a string
func Base91EncodeToString(d []byte) string {
return string(Base91Encode(d))
}
// Base91Encode returns the base91 encoded string
func Base91Encode(d []byte) []byte {
var n, b uint
var o []byte
for i := 0; i < len(d); i++ {
b |= uint(d[i]) << n
n += 8
if n > 13 {
v := b & 8191
if v > 88 {
b >>= 13
n -= 13
} else {
v = b & 16383
b >>= 14
n -= 14
}
o = append(o, enctab[v%91], enctab[v/91])
}
}
if n > 0 {
o = append(o, enctab[b%91])
if n > 7 || b > 90 {
o = append(o, enctab[b/91])
}
}
return o
}
// Base91DecodeToString decodes a given byte array are returns a string
func Base91DecodeString(d string) []byte {
return Base91Decode([]byte(d))
}
// Base91Decode decodes a base91 encoded string and returns the result
func Base91Decode(d []byte) []byte {
var b, n uint
var o []byte
v := -1
for i := 0; i < len(d); i++ {
c, ok := dectab[d[i]]
if !ok {
continue
}
if v < 0 {
v = int(c)
} else {
v += int(c) * 91
b |= uint(v) << n
if v&8191 > 88 {
n += 13
} else {
n += 14
}
o = append(o, byte(b&255))
b >>= 8
n -= 8
for n > 7 {
o = append(o, byte(b&255))
b >>= 8
n -= 8
}
v = -1
}
}
if v+1 > 0 {
o = append(o, byte((b|uint(v)<<n)&255))
}
return o
}
// Base128Encode encodes src into EncodedLen(len(src)) bytes of dst. As a convenience,
// it returns the number of bytes written to dst, but this value is always
// EncodedLen(len(src)).
//
// Encode implements base128 encoding.
func Base128Encode(dst, src []byte) int {
ret := Base128EncodedLen(len(src))
if len(dst) < ret {
panic("dst has insufficient length")
}
dst = dst[:0]
whichByte := uint(1)
bufByte := byte(0)
for _, v := range src {
dst = append(dst, bufByte|(v>>whichByte))
bufByte = (v&(1<<whichByte) - 1) << (7 - whichByte)
if whichByte == 7 {
dst = append(dst, bufByte)
bufByte = 0
whichByte = 0
}
whichByte++
}
dst = append(dst, bufByte)
return ret
}
// Base128Decode decodes src into DecodedLen(len(src)) bytes, returning the actual
// number of bytes written to dst.
//
// If Decode encounters invalid input, it returns an error describing the
// failure.
func Base128Decode(dst, src []byte) (int, error) {
dLen := Base128DecodedLen(len(src))
if Base128EncodedLen(dLen) != len(src) {
return 0, ErrLength
}
if len(dst) < dLen {
panic("dst has insufficient length")
}
dst = dst[:0]
whichByte := uint(1)
bufByte := byte(0)
for _, v := range src {
if (v & 0x80) != 0 {
return len(dst), ErrBit
}
if whichByte > 1 {
dst = append(dst, bufByte|(v>>(8-whichByte)))
}
bufByte = v << whichByte
if whichByte == 8 {
whichByte = 0
}
whichByte++
}
return len(dst), nil
}
// Base128DecodeString returns the bytes represented by the base128 string s.
func Base128DecodeString(s string) ([]byte, error) {
src := []byte(s)
dst := make([]byte, Base128DecodedLen(len(src)))
if _, err := Base128Decode(dst, src); err != nil {
return nil, err
}
return dst, nil
}
// Base128DecodedLen returns the number of bytes `encLen` encoded bytes decodes to.
func Base128DecodedLen(encLen int) int {
return (encLen * 7 / 8)
}
// Base128EncodedLen returns the number of bytes that `dataLen` bytes will encode to.
func Base128EncodedLen(dataLen int) int {
return (((dataLen * 8) + 6) / 7)
}
// Base128EncodeToString returns the base128 encoding of src.
func Base128EncodeToString(src []byte) string {
dst := make([]byte, Base128EncodedLen(len(src)))
Base128Encode(dst, src)
return string(dst)
}
// Base64Encode 输出格式化后的Base64字符串
func Base64Encode(bstr []byte) string {
return base64.StdEncoding.EncodeToString(bstr)
}
// Base64Decode 输出解密前的Base64数据
func Base64Decode(str string) ([]byte, error) {
return base64.StdEncoding.DecodeString(str)
}
// Base85Encode 输出格式化后的Base85字符串
func Base85Encode(bstr []byte) string {
var rtn []byte
rtn = make([]byte, ascii85.MaxEncodedLen(len(bstr)))
ascii85.Encode(rtn, bstr)
return string(rtn)
}
// Base85Decode 输出解密前的Base85数据
func Base85Decode(str string) ([]byte, error) {
var rtn []byte
rtn = make([]byte, len(str))
_, _, err := ascii85.Decode(rtn, []byte(str), true)
return rtn, err
}
func String(bstr []byte) string {
return hex.EncodeToString(bstr)
}
@ -334,58 +107,6 @@ func Sha1Str(bstr []byte) string {
return String(Sha512(bstr))
}
func GenerateKey(bits int) (*rsa.PrivateKey, *rsa.PublicKey, error) {
private, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
return nil, nil, err
}
return private, &private.PublicKey, nil
}
func EncodePrivateKey(private *rsa.PrivateKey) []byte {
return pem.EncodeToMemory(&pem.Block{
Bytes: x509.MarshalPKCS1PrivateKey(private),
Type: "RSA PRIVATE KEY",
})
}
func EncodePublicKey(public *rsa.PublicKey) ([]byte, error) {
publicBytes, err := x509.MarshalPKIXPublicKey(public)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(&pem.Block{
Bytes: publicBytes,
Type: "PUBLIC KEY",
}), nil
}
//EncodeSSHKey
func EncodeSSHKey(public *rsa.PublicKey) ([]byte, error) {
publicKey, err := ssh.NewPublicKey(public)
if err != nil {
return nil, err
}
return ssh.MarshalAuthorizedKey(publicKey), nil
}
func MakeSSHKeyPair() (string, string, error) {
pkey, pubkey, err := GenerateKey(2048)
if err != nil {
return "", "", err
}
pub, err := EncodeSSHKey(pubkey)
if err != nil {
return "", "", err
}
//glog.Info("privateKey=[%s]\n pubKey=[%s]",string(EncodePrivateKey(pkey)),string(pub))
return string(EncodePrivateKey(pkey)), string(pub), nil
}
// SumAll 可以对同一数据进行多种校验
func SumAll(data []byte, method []string) (map[string][]byte, error) {
result := make(map[string][]byte)
@ -659,146 +380,6 @@ func Detach(src string, bytenum int, dst1, dst2 string) error {
return nil
}
// Base85EncodeFile 用base85方法编码src文件到dst文件中去shell传入当前进度
func Base85EncodeFile(src, dst string, shell func(float64)) error {
fpsrc, err := os.Open(src)
if err != nil {
return err
}
defer fpsrc.Close()
stat, _ := os.Stat(src)
filebig := float64(stat.Size())
var sum int64
fpdst, err := os.Create(dst)
if err != nil {
return err
}
defer fpdst.Close()
b85 := ascii85.NewEncoder(fpdst)
defer b85.Close()
for {
buf := make([]byte, 1024000)
n, err := fpsrc.Read(buf)
if err != nil {
if err == io.EOF {
break
}
return err
}
sum += int64(n)
go shell(float64(sum) / filebig * 100)
b85.Write(buf[0:n])
}
return nil
}
// Base85DecodeFile 用base85方法解码src文件到dst文件中去shell传入当前进度
func Base85DecodeFile(src, dst string, shell func(float64)) error {
fpsrc, err := os.Open(src)
if err != nil {
return err
}
defer fpsrc.Close()
stat, _ := os.Stat(src)
filebig := float64(stat.Size())
var sum int64
defer fpsrc.Close()
fpdst, err := os.Create(dst)
if err != nil {
return err
}
defer fpdst.Close()
b85 := ascii85.NewDecoder(fpsrc)
for {
buf := make([]byte, 1280000)
n, err := b85.Read(buf)
if err != nil {
if err == io.EOF {
break
}
return err
}
sum += int64(n)
per := float64(sum) / filebig * 100 / 4.0 * 5.0
if per >= 100 {
per = 100
}
go shell(per)
fpdst.Write(buf[0:n])
}
return nil
}
// Base64EncodeFile 用base64方法编码src文件到dst文件中去shell传入当前进度
func Base64EncodeFile(src, dst string, shell func(float64)) error {
fpsrc, err := os.Open(src)
if err != nil {
return err
}
defer fpsrc.Close()
stat, _ := os.Stat(src)
filebig := float64(stat.Size())
var sum int64 = 0
fpdst, err := os.Create(dst)
if err != nil {
return err
}
defer fpdst.Close()
b64 := base64.NewEncoder(base64.StdEncoding, fpdst)
defer b64.Close()
for {
buf := make([]byte, 1048575)
n, err := fpsrc.Read(buf)
if err != nil {
if err == io.EOF {
break
}
return err
}
sum += int64(n)
go shell(float64(sum) / filebig * 100)
b64.Write(buf[0:n])
}
return nil
}
// Base64DecodeFile 用base64方法解码src文件到dst文件中去shell传入当前进度
func Base64DecodeFile(src, dst string, shell func(float64)) error {
fpsrc, err := os.Open(src)
if err != nil {
return err
}
defer fpsrc.Close()
stat, _ := os.Stat(src)
filebig := float64(stat.Size())
var sum int64 = 0
defer fpsrc.Close()
fpdst, err := os.Create(dst)
if err != nil {
return err
}
defer fpdst.Close()
b64 := base64.NewDecoder(base64.StdEncoding, fpsrc)
for {
buf := make([]byte, 1048576)
n, err := b64.Read(buf)
if err != nil {
if err == io.EOF {
break
}
return err
}
sum += int64(n)
per := float64(sum) / filebig * 100 / 3.0 * 4.0
if per >= 100 {
per = 100
}
go shell(per)
fpdst.Write(buf[0:n])
}
return nil
}
// SplitFile 把src文件按要求分割到dst中去,dst应传入带*号字符串
// 如果bynum=true 则把文件分割成num份
// 如果bynum=false 则把文件按num字节分成多份
@ -904,100 +485,6 @@ func MergeFile(src, dst string, shell func(float64)) error {
return nil
}
// RSAEncrypt RSA公钥加密
func RSAEncrypt(data, public []byte) ([]byte, error) {
blk, _ := pem.Decode(public)
if blk == nil {
return []byte{}, errors.New("public key error")
}
pubkey, err := x509.ParsePKIXPublicKey(blk.Bytes)
if err != nil {
return []byte{}, err
}
return rsa.EncryptPKCS1v15(rand.Reader, pubkey.(*rsa.PublicKey), data)
}
// RSADecrypt RSA私钥解密
func RSADecrypt(data, private []byte, password string) ([]byte, error) {
var prikey *rsa.PrivateKey
var err error
var bytes []byte
blk, _ := pem.Decode(private)
if blk == nil {
return []byte{}, errors.New("private key error")
}
if password != "" {
tmp, err := x509.DecryptPEMBlock(blk, []byte(password))
if err != nil {
return []byte{}, err
}
bytes = tmp
} else {
bytes = blk.Bytes
}
prikey, err = x509.ParsePKCS1PrivateKey(bytes)
if err != nil {
tmp, err := x509.ParsePKCS8PrivateKey(bytes)
if err != nil {
return []byte{}, err
}
prikey = tmp.(*rsa.PrivateKey)
}
return rsa.DecryptPKCS1v15(rand.Reader, prikey, data)
}
// RSASign RSA私钥签名加密
func RSASign(msg, priKey []byte, password string, hashType crypto.Hash) ([]byte, error) {
var prikey *rsa.PrivateKey
var err error
var bytes []byte
blk, _ := pem.Decode(priKey)
if blk == nil {
return []byte{}, errors.New("private key error")
}
if password != "" {
tmp, err := x509.DecryptPEMBlock(blk, []byte(password))
if err != nil {
return []byte{}, err
}
bytes = tmp
} else {
bytes = blk.Bytes
}
prikey, err = x509.ParsePKCS1PrivateKey(bytes)
if err != nil {
tmp, err := x509.ParsePKCS8PrivateKey(bytes)
if err != nil {
return []byte{}, err
}
prikey = tmp.(*rsa.PrivateKey)
}
hashMethod := hashType.New()
_, err = hashMethod.Write(msg)
if err != nil {
return nil, err
}
return rsa.SignPKCS1v15(rand.Reader, prikey, hashType, hashMethod.Sum(nil))
}
// RSAVerify RSA公钥签名验证
func RSAVerify(data, msg, pubKey []byte, hashType crypto.Hash) error {
blk, _ := pem.Decode(pubKey)
if blk == nil {
return errors.New("public key error")
}
pubkey, err := x509.ParsePKIXPublicKey(blk.Bytes)
if err != nil {
return err
}
hashMethod := hashType.New()
_, err = hashMethod.Write(msg)
if err != nil {
return err
}
return rsa.VerifyPKCS1v15(pubkey.(*rsa.PublicKey), hashType, hashMethod.Sum(nil), data)
}
// VicqueEncodeV1 Best
func VicqueEncodeV1(srcdata []byte, key string) []byte {
var keys []int

271
rsa.go

@ -0,0 +1,271 @@
package starcrypto
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"golang.org/x/crypto/ssh"
"math/big"
)
func GenerateKey(bits int) (*rsa.PrivateKey, *rsa.PublicKey, error) {
private, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
return nil, nil, err
}
return private, &private.PublicKey, nil
}
func EncodePrivateKey(private *rsa.PrivateKey) []byte {
return pem.EncodeToMemory(&pem.Block{
Bytes: x509.MarshalPKCS1PrivateKey(private),
Type: "RSA PRIVATE KEY",
})
}
func EncodePublicKey(public *rsa.PublicKey) ([]byte, error) {
publicBytes, err := x509.MarshalPKIXPublicKey(public)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(&pem.Block{
Bytes: publicBytes,
Type: "PUBLIC KEY",
}), nil
}
func DecodePrivateKey(private []byte, password string) (*rsa.PrivateKey, error) {
var prikey *rsa.PrivateKey
var err error
var bytes []byte
blk, _ := pem.Decode(private)
if blk == nil {
return nil, errors.New("private key error")
}
if password != "" {
tmp, err := x509.DecryptPEMBlock(blk, []byte(password))
if err != nil {
return nil, err
}
bytes = tmp
} else {
bytes = blk.Bytes
}
prikey, err = x509.ParsePKCS1PrivateKey(bytes)
if err != nil {
tmp, err := x509.ParsePKCS8PrivateKey(bytes)
if err != nil {
return nil, err
}
prikey = tmp.(*rsa.PrivateKey)
}
return prikey, err
}
func DecodePublicKey(pubStr []byte) (*rsa.PublicKey, error) {
blk, _ := pem.Decode(pubStr)
if blk == nil {
return nil, errors.New("public key error")
}
pub, err := x509.ParsePKIXPublicKey(blk.Bytes)
if err != nil {
return nil, err
}
return pub.(*rsa.PublicKey), nil
}
//EncodeSSHKey
func EncodeSSHKey(public *rsa.PublicKey) ([]byte, error) {
publicKey, err := ssh.NewPublicKey(public)
if err != nil {
return nil, err
}
return ssh.MarshalAuthorizedKey(publicKey), nil
}
func MakeSSHKeyPair(bits int) (string, string, error) {
pkey, pubkey, err := GenerateKey(bits)
if err != nil {
return "", "", err
}
pub, err := EncodeSSHKey(pubkey)
if err != nil {
return "", "", err
}
//glog.Info("privateKey=[%s]\n pubKey=[%s]",string(EncodePrivateKey(pkey)),string(pub))
return string(EncodePrivateKey(pkey)), string(pub), nil
}
// RSAEncrypt RSA公钥加密
func RSAEncrypt(pub *rsa.PublicKey, data []byte) ([]byte, error) {
return rsa.EncryptPKCS1v15(rand.Reader, pub, data)
}
// RSADecrypt RSA私钥解密
func RSADecrypt(prikey *rsa.PrivateKey, data []byte) ([]byte, error) {
return rsa.DecryptPKCS1v15(rand.Reader, prikey, data)
}
// RSASign RSA私钥签名加密
func RSASign(msg, priKey []byte, password string, hashType crypto.Hash) ([]byte, error) {
var prikey *rsa.PrivateKey
var err error
var bytes []byte
blk, _ := pem.Decode(priKey)
if blk == nil {
return []byte{}, errors.New("private key error")
}
if password != "" {
tmp, err := x509.DecryptPEMBlock(blk, []byte(password))
if err != nil {
return []byte{}, err
}
bytes = tmp
} else {
bytes = blk.Bytes
}
prikey, err = x509.ParsePKCS1PrivateKey(bytes)
if err != nil {
tmp, err := x509.ParsePKCS8PrivateKey(bytes)
if err != nil {
return []byte{}, err
}
prikey = tmp.(*rsa.PrivateKey)
}
hashMethod := hashType.New()
_, err = hashMethod.Write(msg)
if err != nil {
return nil, err
}
return rsa.SignPKCS1v15(rand.Reader, prikey, hashType, hashMethod.Sum(nil))
}
// RSAVerify RSA公钥签名验证
func RSAVerify(data, msg, pubKey []byte, hashType crypto.Hash) error {
blk, _ := pem.Decode(pubKey)
if blk == nil {
return errors.New("public key error")
}
pubkey, err := x509.ParsePKIXPublicKey(blk.Bytes)
if err != nil {
return err
}
hashMethod := hashType.New()
_, err = hashMethod.Write(msg)
if err != nil {
return err
}
return rsa.VerifyPKCS1v15(pubkey.(*rsa.PublicKey), hashType, hashMethod.Sum(nil), data)
}
// copy from crypt/rsa/pkcs1v5.go
var hashPrefixes = map[crypto.Hash][]byte{
crypto.MD5: {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10},
crypto.SHA1: {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14},
crypto.SHA224: {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},
crypto.SHA256: {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
crypto.SHA384: {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},
crypto.SHA512: {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
crypto.MD5SHA1: {}, // A special TLS case which doesn't use an ASN1 prefix.
crypto.RIPEMD160: {0x30, 0x20, 0x30, 0x08, 0x06, 0x06, 0x28, 0xcf, 0x06, 0x03, 0x00, 0x31, 0x04, 0x14},
}
// copy from crypt/rsa/pkcs1v5.go
func encrypt(c *big.Int, pub *rsa.PublicKey, m *big.Int) *big.Int {
e := big.NewInt(int64(pub.E))
c.Exp(m, e, pub.N)
return c
}
// copy from crypt/rsa/pkcs1v5.go
func pkcs1v15HashInfo(hash crypto.Hash, inLen int) (hashLen int, prefix []byte, err error) {
// Special case: crypto.Hash(0) is used to indicate that the data is
// signed directly.
if hash == 0 {
return inLen, nil, nil
}
hashLen = hash.Size()
if inLen != hashLen {
return 0, nil, errors.New("crypto/rsa: input must be hashed message")
}
prefix, ok := hashPrefixes[hash]
if !ok {
return 0, nil, errors.New("crypto/rsa: unsupported hash function")
}
return
}
// copy from crypt/rsa/pkcs1v5.go
func leftPad(input []byte, size int) (out []byte) {
n := len(input)
if n > size {
n = size
}
out = make([]byte, size)
copy(out[len(out)-n:], input)
return
}
func unLeftPad(input []byte) (out []byte) {
n := len(input)
t := 2
for i := 2; i < n; i++ {
if input[i] == 0xff {
t = t + 1
} else {
if input[i] == input[0] {
t = t + int(input[1])
}
break
}
}
out = make([]byte, n-t)
copy(out, input[t:])
return
}
// copy&modified from crypt/rsa/pkcs1v5.go
func publicDecrypt(pub *rsa.PublicKey, hash crypto.Hash, hashed []byte, sig []byte) (out []byte, err error) {
hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
if err != nil {
return nil, err
}
tLen := len(prefix) + hashLen
k := (pub.N.BitLen() + 7) / 8
if k < tLen+11 {
return nil, fmt.Errorf("length illegal")
}
c := new(big.Int).SetBytes(sig)
m := encrypt(new(big.Int), pub, c)
em := leftPad(m.Bytes(), k)
out = unLeftPad(em)
err = nil
return
}
func RSAEncryptByPrivkey(privt *rsa.PrivateKey, data []byte) ([]byte, error) {
signData, err := rsa.SignPKCS1v15(nil, privt, crypto.Hash(0), data)
if err != nil {
return nil, err
}
return signData, nil
}
func RSADecryptByPubkey(pub *rsa.PublicKey, data []byte) ([]byte, error) {
decData, err := publicDecrypt(pub, crypto.Hash(0), nil, data)
if err != nil {
return nil, err
}
return decData, nil
}
Loading…
Cancel
Save