it-swarm.com.de

Golang, einen String mit AES und Base64 verschlüsseln

Ich versuche, etwas Text in einer Datenbank zu verschlüsseln, der während des Programmstarts geladen und entschlüsselt werden soll.

Ich habe ein paar Methoden ausprobiert, darunter eine Bibliothek von Drittanbietern https://github.com/richard-lyman/lithcrypt , jedoch ohne Erfolg. Bei Verwendung der folgenden Methode werden 8/10-Elemente verschlüsselt/entschlüsselt, es scheint jedoch, dass ein Teil der Auffüllrückstände irgendwann in der Verschlüsselung/Entschlüsselung zurückbleibt. So wie es aussieht, ist mein Code so:

package client                                                                                                                                                                                              
import (                                                                                                                                                                                                    
    "encoding/base64"                                                                                                                                                                                       
    "crypto/aes"                                                                                                                                                                                            
    "crypto/cipher"                                                                                                                                                                                         
    "fmt"                                                                                                                                                                                                   
) 

var iv = []byte{34, 35, 35, 57, 68, 4, 35, 36, 7, 8, 35, 23, 35, 86, 35, 23}

func encodeBase64(b []byte) string {                                                                                                                                                                        
    return base64.StdEncoding.EncodeToString(b)                                                                                                                                                             
}                                                                                                                                                                                                           

func decodeBase64(s string) []byte {                                                                                                                                                                        
    data, err := base64.StdEncoding.DecodeString(s)                                                                                                                                                         
    if err != nil { panic(err) }                                                                                                                                                                            
    return data                                                                                                                                                                                             
}                                                                                                                                                                                                           

func Encrypt(key, text string) string {                                                                                                                                                                     
    block, err := aes.NewCipher([]byte(key))                                                                                                                                                                
    if err != nil { panic(err) }                                                                                                                                                                            
    plaintext := []byte(text)                                                                                                                                                                               
    cfb := cipher.NewCFBEncrypter(block, iv)                                                                                                                                                                
    ciphertext := make([]byte, len(plaintext))                                                                                                                                                              
    cfb.XORKeyStream(ciphertext, plaintext)                                                                                                                                                                 
    return encodeBase64(ciphertext)                                                                                                                                                                         
}                                                                                                                                                                                                           

func Decrypt(key, text string) string {                                                                                                                                                                     
    block, err := aes.NewCipher([]byte(key))                                                                                                                                                                
    if err != nil { panic(err) }                                                                                                                                                                            
    ciphertext := decodeBase64(text)                                                                                                                                                                        
    cfb := cipher.NewCFBEncrypter(block, iv)                                                                                                                                                                
    plaintext := make([]byte, len(ciphertext))                                                                                                                                                              
    cfb.XORKeyStream(plaintext, ciphertext)                                                                                                                                                                 
}                          

Es wurde mir gesagt, dass ich vielleicht die Zeichenfolge auffüllen muss, aber es scheint seltsam, dass ich eine Stream-Chiffre auffüllen müsste. 

Unten ist ein Beispiel für diesen Fehler: http://play.golang.org/p/4FQBAeHgRs

31
jawr

Dies basiert auf den Beispielen NewCFBEncrypter/NewCFBDecrypter und scheint das zu tun, was Sie benötigen:

EDIT: Basierend auf Kluygs Kommentar zur IV-Erstellung habe ich den Beispielcode für die Verwendung von geändert empfohlene Methode zum Erstellen der IV aus dem Geheimtext Dieselbe Methode wie im linked - Beispiel, um die IV aus dem Chiffretext zu erstellen. (Im Produktionscode sollte die IV jedes Mal separat generiert werden. Danke an RoundSparrow hilltx für diesen Hinweis.)

Ich denke, das Problem, auf das Sie stoßen, liegt in einer ungültigen Schlüssellänge, aber ich bin nicht zu 100% sicher.

package main

import (
    "crypto/aes"
    "crypto/cipher"
    "crypto/Rand"
    "encoding/base64"
    "errors"
    "fmt"
    "io"
    "log"
)

func main() {
    key := []byte("a very very very very secret key") // 32 bytes
    plaintext := []byte("some really really really long plaintext")
    fmt.Printf("%s\n", plaintext)
    ciphertext, err := encrypt(key, plaintext)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%0x\n", ciphertext)
    result, err := decrypt(key, ciphertext)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%s\n", result)
}

// See alternate IV creation from ciphertext below
//var iv = []byte{35, 46, 57, 24, 85, 35, 24, 74, 87, 35, 88, 98, 66, 32, 14, 05}

func encrypt(key, text []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err != nil {
        return nil, err
    }
    b := base64.StdEncoding.EncodeToString(text)
    ciphertext := make([]byte, aes.BlockSize+len(b))
    iv := ciphertext[:aes.BlockSize]
    if _, err := io.ReadFull(Rand.Reader, iv); err != nil {
        return nil, err
    }
    cfb := cipher.NewCFBEncrypter(block, iv)
    cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b))
    return ciphertext, nil
}

func decrypt(key, text []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err != nil {
        return nil, err
    }
    if len(text) < aes.BlockSize {
        return nil, errors.New("ciphertext too short")
    }
    iv := text[:aes.BlockSize]
    text = text[aes.BlockSize:]
    cfb := cipher.NewCFBDecrypter(block, iv)
    cfb.XORKeyStream(text, text)
    data, err := base64.StdEncoding.DecodeString(string(text))
    if err != nil {
        return nil, err
    }
    return data, nil
}

Produziert:

etwas wirklich sehr, sehr langer Klartext
54618bd6bb10612a7b590c53192df214501e01b685540b012581a0ed9ff3ddaa1f4177cc6186b501fb8cce0c2eb764daff475aab724d4d33e614d89cf556
etwas wirklich sehr, sehr langer Klartext 

Spielplatz

Hoffe, das hilft, das Problem zu lokalisieren.

52
Intermernet

Crypto ist schwer und die Go-Bibliotheken sind vielleicht nicht hoch genug, so dass es leicht ist, Fehler zu machen. 

Für alle, die nach einem Beispiel suchen, das von einem Experten auf diesem Gebiet (einem Sicherheitsentwickler bei CoreOS) richtig gemacht wird, ist dies ein gutes Beispiel für die AES-Verschlüsselung (zusammen mit anderen üblichen Krypto-Anwendungen). 

https://github.com/gtank/cryptopasta

7
Kenny Grant

Hier ist die funktionierende Demo, die ich gerade fertiggestellt habe. Sie verwendet hauptsächlich Codebeispiele aus dem go-Dokument, ist jedoch darauf zugeschnitten, was die meisten Apps einschließlich meines Anwendungsfalls von Verschlüsselungsmethoden erwarten.

Es wird die AES-Verschlüsselung . Von String zu Base64-String verschlüsselt. Einfach zu verwenden für URL und dbs . Entschlüsseln von der oben erstellten Base64-Zeichenfolge zum ursprünglichen Text.

Einfache Textkonvertierungen überall.

Gist: Hier ist der Gist, bitte lass es mich wissen, wenn Verbesserungsbedarf besteht.

Es ist eine einfache Go-Datei, die ausgeführt werden kann.

4
mamu

Es scheint, dass Ihre Reihenfolge der Operationen etwas rückwärts ist. Folgendes scheint Sie zu tun:

ct = encrypt(encode(pt))
pt = decode(decrypt(ct))

Es sollte eher aussehen:

ct = encode(encrypt(pt))
pt = decrypt(decode(ct))

Folgendes funktioniert für mich

func Encrypt(key, text []byte) string {
    block, err := aes.NewCipher(key)
    if err != nil {
        panic(err)
    }
    ciphertext := make([]byte, aes.BlockSize+len(text))
    iv := ciphertext[:aes.BlockSize]
    if _, err := io.ReadFull(crand.Reader, iv); err != nil {
        panic(err)
    }
    cfb := cipher.NewCFBEncrypter(block, iv)
    cfb.XORKeyStream(ciphertext[aes.BlockSize:], text)
    return encodeBase64(ciphertext)
}


func Decrypt(key []byte, b64 string) string {
    text := decodeBase64(b64)
    block, err := aes.NewCipher(key)
    if err != nil {
        panic(err)
    }
    if len(text) < aes.BlockSize {
        panic("ciphertext too short")
    }
    iv := text[:aes.BlockSize]
    text = text[aes.BlockSize:]
    cfb := cipher.NewCFBDecrypter(block, iv)
    cfb.XORKeyStream(text, text)
    return string(text)
}
3
user79854

Microservice der symmetrischen Verschlüsselung (Blowfish) auf Golang . https://github.com/kl09/encrypt

0
kl09