summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew <saintruler@gmail.com>2021-04-30 10:28:16 +0400
committerAndrew <saintruler@gmail.com>2021-04-30 10:28:16 +0400
commit587ac4f7fecc417b4877c5f3c0fdefa58990b3c8 (patch)
treeeeba2f4ec3a0a276f860abc7411c969a8cb39e96
parent0106c0f8e013977cbc96f17f3c95e38d2d5ea854 (diff)
Added signer app
-rw-r--r--playground/cryptography.go136
-rw-r--r--playground/go.mod3
-rw-r--r--playground/main.go87
3 files changed, 226 insertions, 0 deletions
diff --git a/playground/cryptography.go b/playground/cryptography.go
new file mode 100644
index 0000000..6220683
--- /dev/null
+++ b/playground/cryptography.go
@@ -0,0 +1,136 @@
+package main
+
+import (
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/sha256"
+ "crypto/x509"
+ "encoding/asn1"
+ "encoding/base64"
+ "encoding/pem"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "strings"
+)
+
+const KeyBitSize = 4096
+
+func readFile(filename string) ([]byte, error) {
+ file, err := os.Open(filename)
+ if err != nil {
+ return nil, err
+ }
+
+ return ioutil.ReadAll(file)
+}
+
+func writeFile(filename string, data []byte) error {
+ file, err := os.Create(filename)
+ if err != nil {
+ return err
+ }
+
+ _, err = file.Write(data)
+ return err
+}
+
+func signData(data []byte, key *rsa.PublicKey) (string, error) {
+ based := base64.StdEncoding.EncodeToString(data)
+ h := sha256.Sum256([]byte(based))
+ dataHash := fmt.Sprintf("%x", h)
+
+
+ ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, key, []byte(dataHash))
+ if err != nil {
+ return "", err
+ }
+
+ signature := base64.StdEncoding.EncodeToString(ciphertext)
+ return fmt.Sprintf("%s.%s", based, signature), nil
+}
+
+func checkSignature(signedData string, key *rsa.PrivateKey) (bool, error) {
+ spl := strings.Split(signedData, ".")
+ data := spl[0]
+ signature := spl[1]
+
+ dataHash := fmt.Sprintf("%x", sha256.Sum256([]byte(data)))
+
+ decodedSign, err := base64.StdEncoding.DecodeString(signature)
+ if err != nil {
+ return false, err
+ }
+
+ signHash, err := decodeMessage(decodedSign, key)
+ if err != nil {
+ return false, err
+ }
+
+ return dataHash == string(signHash), nil
+}
+
+func encodeMessage(message []byte, key *rsa.PrivateKey) ([]byte, error) {
+ ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, &key.PublicKey, message)
+ if err != nil {
+ return nil, err
+ }
+ return ciphertext, nil
+}
+
+func decodeMessage(ciphertext []byte, key *rsa.PrivateKey) ([]byte, error) {
+ plaintext, err := rsa.DecryptPKCS1v15(rand.Reader, key, ciphertext)
+ if err != nil { return nil, err }
+ return plaintext, nil
+}
+
+func loadPublicPEM(filename string) (*rsa.PublicKey, error) {
+ pemBytes, err := readFile(filename)
+ if err != nil {
+ return nil, err
+ }
+
+ block, _ := pem.Decode(pemBytes)
+ if block == nil {
+ return nil, errors.New("there is no key in file")
+ }
+
+ return x509.ParsePKCS1PublicKey(block.Bytes)
+}
+
+func loadPrivatePEM(filename string) (*rsa.PrivateKey, error) {
+ pemBytes, err := readFile(filename)
+ if err != nil {
+ return nil, err
+ }
+
+ block, _ := pem.Decode(pemBytes)
+ if block == nil {
+ return nil, errors.New("there is no key in file")
+ }
+
+ return x509.ParsePKCS1PrivateKey(block.Bytes)
+}
+
+func generateKeys() (keys *rsa.PrivateKey, private []byte, public []byte, err error) {
+ key, err := rsa.GenerateKey(rand.Reader, KeyBitSize)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+
+ var privateKey = &pem.Block{
+ Type: "PRIVATE KEY",
+ Bytes: x509.MarshalPKCS1PrivateKey(key),
+ }
+
+ asn1Bytes, _ := asn1.Marshal(key.PublicKey)
+ var publicKey = &pem.Block{
+ Type: "PUBLIC KEY",
+ Bytes: asn1Bytes,
+ }
+
+ bytePrivate := pem.EncodeToMemory(privateKey)
+ bytePublic := pem.EncodeToMemory(publicKey)
+ return key, bytePrivate, bytePublic, nil
+}
diff --git a/playground/go.mod b/playground/go.mod
new file mode 100644
index 0000000..7af8b27
--- /dev/null
+++ b/playground/go.mod
@@ -0,0 +1,3 @@
+module vasthecat.ru/playground
+
+go 1.16
diff --git a/playground/main.go b/playground/main.go
new file mode 100644
index 0000000..b8574f0
--- /dev/null
+++ b/playground/main.go
@@ -0,0 +1,87 @@
+package main
+
+import (
+ "fmt"
+ "os"
+)
+
+func runGeneration() {
+ _, privateBytes, publicBytes, err := generateKeys()
+ if err != nil {
+ fmt.Printf("Произошла ошибка при генерации ключей: %s\n", err)
+ os.Exit(1)
+ }
+
+ err = writeFile(os.Args[2], privateBytes)
+ if err != nil {
+ fmt.Printf("%s\n", err)
+ os.Exit(1)
+ }
+ err = writeFile(os.Args[3], publicBytes)
+ if err != nil {
+ fmt.Printf("%s\n", err)
+ os.Exit(1)
+ }
+}
+
+func runSign() {
+ keyFile := os.Args[2]
+ messageFile := os.Args[3]
+ resultFile := os.Args[4]
+
+ key, err := loadPublicPEM(keyFile)
+
+ message, err := readFile(messageFile)
+ if err != nil {
+ fmt.Printf("%s\n", err)
+ os.Exit(1)
+ }
+ signedMessage, err := signData(message, key)
+ if err != nil {
+ fmt.Printf("Произошла ошибка при подписи данных: %s\n", err)
+ os.Exit(1)
+ }
+ err = writeFile(resultFile, []byte(signedMessage))
+ if err != nil {
+ fmt.Printf("%s\n", err)
+ os.Exit(1)
+ }
+}
+
+func runCheck() {
+ keyFile := os.Args[2]
+ signedFile := os.Args[3]
+
+ key, err := loadPrivatePEM(keyFile)
+ if err != nil {
+ fmt.Printf("%s\n", err)
+ os.Exit(1)
+ }
+
+ data, err := readFile(signedFile)
+ if err != nil {
+ fmt.Printf("%s\n", err)
+ os.Exit(1)
+ }
+ result, err := checkSignature(string(data), key)
+ if err != nil {
+ fmt.Printf("%s\n", err)
+ os.Exit(1)
+ }
+
+ if result {
+ fmt.Println("Подпись верна")
+ } else {
+ fmt.Println("Подпись не верна")
+ }
+}
+
+func main() {
+ if os.Args[1] == "generate" {
+ runGeneration()
+ } else if os.Args[1] == "sign" {
+ runSign()
+ } else if os.Args[1] == "check" {
+ runCheck()
+ }
+}