Fix crypto
parent
da4224ba23
commit
02e6457443
@ -0,0 +1,117 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
cipher2 "crypto/cipher"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"golang.org/x/crypto/blowfish"
|
||||
"io"
|
||||
)
|
||||
|
||||
type BaseMessage struct {
|
||||
Signature string
|
||||
}
|
||||
|
||||
func DecryptAndVerify(input []byte, key *rsa.PrivateKey, pub *rsa.PublicKey, signature []byte, v interface{}) error {
|
||||
all, err := hex.DecodeString(string(input))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
encPasswordAndIV := all[:512]
|
||||
encBody := all[512:]
|
||||
|
||||
passwordAndIV, err := rsa.DecryptPKCS1v15(rand.Reader, key, encPasswordAndIV)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
password := passwordAndIV[:32]
|
||||
iv := passwordAndIV[32:]
|
||||
|
||||
cipher, err := blowfish.NewCipher(password)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
body := make([]byte, len(encBody))
|
||||
dec := cipher2.NewCBCDecrypter(cipher, iv)
|
||||
dec.CryptBlocks(body, encBody)
|
||||
err = json.Unmarshal(body, v)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
baseReq, ok := v.(*BaseMessage)
|
||||
if !ok {
|
||||
return errors.New("non-base request")
|
||||
}
|
||||
|
||||
recvSignature, err := hex.DecodeString(baseReq.Signature)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fingerprint := signature
|
||||
fingerprintHashed := sha256.Sum256(fingerprint)
|
||||
err = rsa.VerifyPKCS1v15(pub, 0, fingerprintHashed[:], recvSignature)
|
||||
return err
|
||||
}
|
||||
|
||||
func EncryptAndSign(v interface{}, key *rsa.PrivateKey, pub *rsa.PublicKey, signature []byte, writer io.Writer) error {
|
||||
passwordAndIV := make([]byte, 40)
|
||||
_, err := rand.Read(passwordAndIV)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
encPasswordAndIV, err := rsa.EncryptPKCS1v15(rand.Reader, pub, passwordAndIV)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = writer.Write([]byte(hex.EncodeToString(encPasswordAndIV)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
password := passwordAndIV[:32]
|
||||
iv := passwordAndIV[32:]
|
||||
|
||||
cipher, err := blowfish.NewCipher(password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hashedFingerpint := sha256.Sum256(signature)
|
||||
plainSignature, err := rsa.SignPKCS1v15(rand.Reader, key, 0, hashedFingerpint[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sign, ok := v.(*BaseMessage)
|
||||
if !ok {
|
||||
return errors.New("given message can't be signed")
|
||||
}
|
||||
sign.Signature = hex.EncodeToString(plainSignature)
|
||||
|
||||
body, err := json.Marshal(v)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
encBody := make([]byte, len(body))
|
||||
enc := cipher2.NewCBCEncrypter(cipher, iv)
|
||||
enc.CryptBlocks(encBody, body)
|
||||
writer.Write([]byte(hex.EncodeToString(encBody)))
|
||||
|
||||
return nil
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package service_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"git.cijber.net/zer.ooo/service"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSingleRound(t *testing.T) {
|
||||
keyA, _ := rsa.GenerateKey(rand.Reader, 4096)
|
||||
keyB, _ := rsa.GenerateKey(rand.Reader, 4096)
|
||||
signature := []byte("Hello world!")
|
||||
v := &service.BaseMessage{}
|
||||
x := make([]byte, 0)
|
||||
b := bytes.NewBuffer(x)
|
||||
err := service.EncryptAndSign(v, keyA, &keyB.PublicKey, signature, b)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Failed encrypting: %s", err)
|
||||
}
|
||||
|
||||
err = service.DecryptAndVerify(b.Bytes(), keyB, &keyA.PublicKey, signature, &service.BaseMessage{})
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Failed decrypting: %s", err)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue