191 lines
5.7 KiB
Go
191 lines
5.7 KiB
Go
package crypto
|
|
|
|
import (
|
|
"crypto/aes"
|
|
"crypto/cipher"
|
|
"crypto/rand"
|
|
"crypto/rsa"
|
|
"crypto/sha256"
|
|
"crypto/x509"
|
|
"encoding/base64"
|
|
"encoding/hex"
|
|
"encoding/pem"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
)
|
|
|
|
// HashToken hashes a token using SHA-256.
|
|
func HashToken(token string) string {
|
|
hash := sha256.Sum256([]byte(token))
|
|
return hex.EncodeToString(hash[:])
|
|
}
|
|
|
|
// VerifyToken compares a plaintext token with a stored hash.
|
|
func VerifyToken(token, storedHash string) bool {
|
|
return HashToken(token) == storedHash
|
|
}
|
|
|
|
// 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)
|
|
}
|
|
publicKey := &privateKey.PublicKey
|
|
exportPrivateKeyToPEM(privateKey)
|
|
exportPublicKeyToPEM(publicKey)
|
|
return exportPrivateKeyToPEM(privateKey), exportPublicKeyToPEM(publicKey)
|
|
}
|
|
|
|
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)
|
|
}
|
|
encryptedString := base64.StdEncoding.EncodeToString(encryptedBytes)
|
|
return encryptedString
|
|
}
|
|
|
|
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)
|
|
}
|
|
decryptedString := string(decryptedBytes)
|
|
return decryptedString
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// 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
|
|
func exportPrivateKeyToPEM(privateKey *rsa.PrivateKey) string {
|
|
privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey)
|
|
privateKeyPEM := pem.EncodeToMemory(&pem.Block{
|
|
Type: "RSA PRIVATE KEY",
|
|
Bytes: privateKeyBytes,
|
|
})
|
|
return string(privateKeyPEM)
|
|
}
|
|
|
|
// Funktion, um den öffentlichen Schlüssel in PEM-Format zu exportieren
|
|
func exportPublicKeyToPEM(publicKey *rsa.PublicKey) string {
|
|
publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey)
|
|
if err != nil {
|
|
log.Fatalf("Fehler beim Exportieren des öffentlichen Schlüssels: %v", err)
|
|
}
|
|
publicKeyPEM := pem.EncodeToMemory(&pem.Block{
|
|
Type: "PUBLIC KEY",
|
|
Bytes: publicKeyBytes,
|
|
})
|
|
return string(publicKeyPEM)
|
|
}
|