diff --git a/crypto/crypto.go b/crypto/crypto.go index ba4d38c..94e2488 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -1,6 +1,8 @@ package crypto import ( + "crypto/aes" + "crypto/cipher" "crypto/rand" "crypto/rsa" "crypto/sha256" @@ -8,7 +10,9 @@ import ( "encoding/base64" "encoding/hex" "encoding/pem" + "errors" "fmt" + "io" "log" ) @@ -23,46 +27,143 @@ func VerifyToken(token, storedHash string) bool { return HashToken(token) == storedHash } -func main() string { - // 1. Generiere einen privaten Schlüssel +// Verschlüsselt einen JSON-String mit AES-GCM +func AES_Encrypt(jsonString string, key []byte) (string, error) { + // Erstelle einen AES-Block + block, err := aes.NewCipher(key) + if err != nil { + return "", fmt.Errorf("Fehler beim Erstellen des AES-Blocks: %v", err) + } + + // AES-GCM-Modus initialisieren + aesGCM, err := cipher.NewGCM(block) + if err != nil { + return "", fmt.Errorf("Fehler beim Erstellen von AES-GCM: %v", err) + } + + // Generiere eine zufällige Nonce (einmaliger Wert) + nonce := make([]byte, aesGCM.NonceSize()) + if _, err := io.ReadFull(rand.Reader, nonce); err != nil { + return "", fmt.Errorf("Fehler beim Generieren der Nonce: %v", err) + } + + // JSON-Daten verschlüsseln + ciphertext := aesGCM.Seal(nil, nonce, []byte(jsonString), nil) + + // Nonce und Ciphertext zusammenfügen und Base64-kodieren + result := append(nonce, ciphertext...) + return base64.StdEncoding.EncodeToString(result), nil +} + +// Entschlüsselt einen verschlüsselten JSON-String mit AES-GCM +func AES_Decrypt(encryptedString string, key []byte) (string, error) { + // Base64-Dekodierung + data, err := base64.StdEncoding.DecodeString(encryptedString) + if err != nil { + return "", fmt.Errorf("Fehler beim Base64-Dekodieren: %v", err) + } + + // Erstelle einen AES-Block + block, err := aes.NewCipher(key) + if err != nil { + return "", fmt.Errorf("Fehler beim Erstellen des AES-Blocks: %v", err) + } + + // AES-GCM-Modus initialisieren + aesGCM, err := cipher.NewGCM(block) + if err != nil { + return "", fmt.Errorf("Fehler beim Erstellen von AES-GCM: %v", err) + } + + // Extrahiere die Nonce und den Ciphertext + nonceSize := aesGCM.NonceSize() + if len(data) < nonceSize { + return "", errors.New("Ungültige verschlüsselte Daten") + } + nonce, ciphertext := data[:nonceSize], data[nonceSize:] + + // JSON-Daten entschlüsseln + plaintext, err := aesGCM.Open(nil, nonce, ciphertext, nil) + if err != nil { + return "", fmt.Errorf("Fehler beim Entschlüsseln: %v", err) + } + + return string(plaintext), nil +} + +func RSA_GenerateKeyPair() (string, string) { privateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { log.Fatalf("Fehler beim Generieren des privaten Schlüssels: %v", err) } - - // 2. Extrahiere den öffentlichen Schlüssel publicKey := &privateKey.PublicKey + exportPrivateKeyToPEM(privateKey) + exportPublicKeyToPEM(publicKey) + return exportPrivateKeyToPEM(privateKey), exportPublicKeyToPEM(publicKey) +} - // 3. Beispieltext zum Verschlüsseln - plainText := "Dies ist ein geheimer String!" - - // 4. Verschlüssle den Text mit dem öffentlichen Schlüssel - encryptedBytes, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, []byte(plainText)) +func RSA_Encrypt(PublicKey, PlainText string) string { + PuK, err1 := importPublicKeyFromPEM(PublicKey) + if err1 != nil { + log.Fatalf("Fehler beim Importieren des öffentlichen Schlüssels: %v", err1) + } + encryptedBytes, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, PuK, []byte(PlainText), nil) if err != nil { log.Fatalf("Fehler beim Verschlüsseln: %v", err) } - - // Kodierung des verschlüsselten Textes in Base64 für Lesbarkeit encryptedString := base64.StdEncoding.EncodeToString(encryptedBytes) - fmt.Println("Verschlüsselter Text (Base64):", encryptedString) + return encryptedString +} - // 5. Entschlüssle den Text mit dem privaten Schlüssel - decryptedBytes, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, encryptedBytes) +func RSA_Decrypt(PrivateKey, EncryptedText string) string { + PrK, err1 := importPrivateKeyFromPEM(PrivateKey) + if err1 != nil { + log.Fatalf("Fehler beim Importieren des privaten Schlüssels: %v", err1) + } + encryptedstring, err2 := base64.StdEncoding.DecodeString(EncryptedText) + if err2 != nil { + log.Fatalf("Fehler beim Decodieren des verschlüsselten Textes: %v", err2) + } + encryptedBytes := []byte(encryptedstring) + decryptedBytes, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, PrK, encryptedBytes, nil) if err != nil { log.Fatalf("Fehler beim Entschlüsseln: %v", err) } - - // 6. Gib den entschlüsselten Text aus decryptedString := string(decryptedBytes) - fmt.Println("Entschlüsselter Text:", decryptedString) + return decryptedString +} - // 7. (Optional) Exportiere und Importiere die Schlüssel - privateKeyPEM := exportPrivateKeyToPEM(privateKey) - fmt.Println("\nPrivate Key (PEM):\n", privateKeyPEM) +// Importiere einen privaten Schlüssel aus einem PEM-String +func importPrivateKeyFromPEM(pemString string) (*rsa.PrivateKey, error) { + block, _ := pem.Decode([]byte(pemString)) + if block == nil || block.Type != "RSA PRIVATE KEY" { + return nil, errors.New("Ungültiges PEM-Format oder kein privater Schlüssel") + } + privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + return nil, err + } + return privateKey, nil +} - publicKeyPEM := exportPublicKeyToPEM(publicKey) - fmt.Println("\nPublic Key (PEM):\n", publicKeyPEM) - return "" +// Importiere einen öffentlichen Schlüssel aus einem PEM-String +func importPublicKeyFromPEM(pemString string) (*rsa.PublicKey, error) { + block, _ := pem.Decode([]byte(pemString)) + if block == nil || block.Type != "PUBLIC KEY" { + return nil, errors.New("Ungültiges PEM-Format oder kein öffentlicher Schlüssel") + } + publicKey, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + return nil, err + } + + // Überprüfe den Typ des Schlüssels + switch pub := publicKey.(type) { + case *rsa.PublicKey: + return pub, nil + default: + return nil, errors.New("Öffentlicher Schlüssel ist kein RSA-Schlüssel") + } } // Funktion, um den privaten Schlüssel in PEM-Format zu exportieren diff --git a/netproto/netproto.go b/netproto/netproto.go index 790829b..4565aaa 100644 --- a/netproto/netproto.go +++ b/netproto/netproto.go @@ -19,12 +19,25 @@ const ( ExtensionHeaderType_Destination uint8 = 2 /* https://git.send.nrw/sendnrw/sendnrwlib/issues/1 */ ExtensionHeaderType_PayloadDefinition uint8 = 3 ExtensionHeaderType_Protocol uint8 = 4 - ExtensionHeaderType_Control uint8 = 5 /*Steuerbefehle wie Download, Upload, ...*/ + ExtensionHeaderType_Control uint8 = 5 /*Syn/SynAck/Ack/AckFin/Fin*/ ExtensionHeaderType_Crypto uint8 = 6 /*Hinweis auf eine Verschlüsselung*/ ExtensionHeaderType_Validation uint8 = 7 /*Hinweis auf eine Validierung oder Checksum*/ ExtensionHeaderType_Routing uint8 = 8 /*Hinweis auf eine Routing-Information*/ ) +const ( + ControlFlag_Flow_SYN string = "SYN" + ControlFlag_Flow_SYNACK string = "SYNACK" + ControlFlag_Flow_ACK string = "ACK" + ControlFlag_Flow_ACKFIN string = "ACKFIN" + ControlFlag_Flow_FIN string = "FIN" + ControlFlag_Encryption_INSECURE string = "INSECURE" + ControlFlag_Encryption_STAYINSECURE string = "STAYINSECURE" + ControlFlag_Encryption_SECURESTART string = "SECURESTART" + ControlFlag_Encryption_SECUREACCEPT string = "SECUREACCEPT" + ControlFlag_Encryption_SECUREFAIL string = "SECUREFAIL" +) + func GenerateEHT1(IPv4, IPv6, Port string) ExtensionHeader { return ExtensionHeader{ Type: ExtensionHeaderType_Source, @@ -57,6 +70,22 @@ func GenerateEHT4(ProtocolName, ProtocolVersion, ProtocolOID string) ExtensionHe } } +func GenerateEHT5(ControlFlagFlow, ControlFlagEncryption string) ExtensionHeader { + return ExtensionHeader{ + Type: ExtensionHeaderType_Control, + Meta: map[string]string{"version": "1.0"}, + Data: map[string]string{"controlflagflow": ControlFlagFlow, "controlflagencryption": ControlFlagEncryption}, + } +} + +func GenerateEHT6(PublicKey string) ExtensionHeader { + return ExtensionHeader{ + Type: ExtensionHeaderType_Crypto, + Meta: map[string]string{"version": "1.0"}, + Data: map[string]string{"publickey": PublicKey}, + } +} + func GenerateEHT7(Checksum string) ExtensionHeader { return ExtensionHeader{ Type: ExtensionHeaderType_Validation, @@ -65,18 +94,26 @@ func GenerateEHT7(Checksum string) ExtensionHeader { } } -func GenerateMH(Version uint8, Flag string) MainHeader { +func GenerateMainHeader(Version uint8, Flag string, ExH ...ExtensionHeader) MainHeader { return MainHeader{ - Version: Version, - Meta: map[string]string{"version": "1.0", "flag": Flag}, + Version: Version, + Meta: map[string]string{"version": "1.0", "flag": Flag}, + ExtensionHeaders: ExH, } } -func EncodeB64(input string) (string, error) { +func GenerateNetworkProtocol(mainheader MainHeader, payload string) NetworkProtocol { + return NetworkProtocol{ + Header: mainheader, + Payload: payload, + } +} + +func EncodeBase64(input string) (string, error) { return base64.StdEncoding.EncodeToString([]byte(input)), nil } -func DecodeB64(input string) (string, error) { +func DecodeBase64(input string) (string, error) { d, err := base64.StdEncoding.DecodeString(input) if err != nil { return "", err