package main import ( "crypto/aes" "crypto/cipher" "crypto/rand" "crypto/rsa" "crypto/sha256" "encoding/base64" "encoding/json" "net/http" encrypt "fckeuspy-go/lib" ) func NewServer() *http.ServeMux { server := &http.ServeMux{} // 3) routing server.HandleFunc("/", indexHandler) server.HandleFunc("/public.pem", publicKeyHandler) server.HandleFunc("/public.crt", publicCertHandler) server.HandleFunc("/encrypt", encryptHandler) server.HandleFunc("/decrypt", decryptHandler) server.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) // log.Println("Server běží na http://localhost:8080") return server } func indexHandler(w http.ResponseWriter, r *http.Request) { _ = tmpl.ExecuteTemplate(w, "index.html", nil) } func publicKeyHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/x-pem-file") w.Write(pubPEM) } func publicCertHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/x-pem-file") w.Write(certPEM) } func encryptHandler(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { http.Error(w, "Bad form", http.StatusBadRequest) return } msg := r.Form.Get("message") peer := r.Form.Get("pubkey") // může to být PEM PUBLIC KEY nebo CERT pubKey, err := encrypt.ParsePeerPublicKey(peer) if err != nil { http.Error(w, "Neplatný public key/cert: "+err.Error(), http.StatusBadRequest) return } // --- hybrid: AES-GCM + RSA-OAEP(SHA-256) --- // 1) vygeneruj náhodný sym. klíč aesKey := make([]byte, 32) // AES-256 if _, err := rand.Read(aesKey); err != nil { http.Error(w, "Rand fail", 500) return } block, err := aes.NewCipher(aesKey) if err != nil { http.Error(w, "AES fail", 500) return } gcm, err := cipher.NewGCM(block) if err != nil { http.Error(w, "GCM fail", 500) return } nonce := make([]byte, gcm.NonceSize()) if _, err := rand.Read(nonce); err != nil { http.Error(w, "Nonce fail", 500) return } ciphertext := gcm.Seal(nil, nonce, []byte(msg), nil) // 2) zašifruj AES klíč cizím RSA klíčem (OAEP SHA-256) label := []byte{} // prázdný label ek, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, pubKey, aesKey, label) if err != nil { http.Error(w, "RSA-OAEP fail: "+err.Error(), 500) return } env := envelope{ EK: base64.StdEncoding.EncodeToString(ek), N: base64.StdEncoding.EncodeToString(nonce), CT: base64.StdEncoding.EncodeToString(ciphertext), } payload, _ := json.MarshalIndent(env, "", " ") _ = tmpl.ExecuteTemplate(w, "encrypt.html", string(payload)) } func decryptHandler(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { http.Error(w, "Bad form", http.StatusBadRequest) return } in := r.Form.Get("payload") var env envelope if err := json.Unmarshal([]byte(in), &env); err != nil { http.Error(w, "Neplatné JSON", 400) return } ek, err := base64.StdEncoding.DecodeString(env.EK) if err != nil { http.Error(w, "ek base64", 400) return } nonce, err := base64.StdEncoding.DecodeString(env.N) if err != nil { http.Error(w, "nonce base64", 400) return } ct, err := base64.StdEncoding.DecodeString(env.CT) if err != nil { http.Error(w, "ct base64", 400) return } // 1) rozšifruj AES klíč naším RSA label := []byte{} aesKey, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, priv, ek, label) if err != nil { http.Error(w, "RSA-OAEP decrypt fail: "+err.Error(), 400) return } block, err := aes.NewCipher(aesKey) if err != nil { http.Error(w, "AES fail", 500) return } gcm, err := cipher.NewGCM(block) if err != nil { http.Error(w, "GCM fail", 500) return } plain, err := gcm.Open(nil, nonce, ct, nil) if err != nil { http.Error(w, "GCM open fail: "+err.Error(), 400) return } _ = tmpl.ExecuteTemplate(w, "decrypt.html", string(plain)) }