2016-03-31 18 views
0

Ich verwende AES-Verschlüsselung in Go und PHP. Beide Sprachen verschlüsseln/entschlüsseln jedoch nicht den jeweils anderen Chiffretext. Im Anschluss i in php versucht habenAES-Verschlüsselung mit Go und PHP

 class Crypto { 
    private $encryptKey = "keyforencryption"; 
    private $iv = 'ivusedforencrypt'; 
    private $blocksize = 16; 
    public function encrypt($toEncrypt){ 
     $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CFB); 
     //$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); 
     return base64_encode($this->iv . mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->encryptKey, $toEncrypt, MCRYPT_MODE_CFB, $this->iv)); 
    } 

    public function decrypt($toDecrypt){ 
     $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CFB);//$this->blocksize; 
     $toDecrypt = base64_decode($toDecrypt); 
     return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->encryptKey, substr($toDecrypt, $iv_size), MCRYPT_MODE_CFB, substr($toDecrypt, 0, $iv_size))); 
    } 

} 

$c = new Crypto(); 
echo "Encrypted : ".$e = $c->encrypt("test"); 
echo "<br/>Decrypted : ".$c->decrypt($e); 

Ausgang: aXZ1c2VkZm9yZW5jcnlwdDpdZEinU2rB

und dieses in Go mit AES

package main 

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

func main() { 
    key := []byte("keyforencryption") 
    plaintext := []byte("test") 
    fmt.Printf("%s\n", plaintext) 
    ciphertext, err := encrypt(key, plaintext) 
    if err != nil { 
     log.Fatal(err) 
    } 
    b := base64.StdEncoding.EncodeToString(ciphertext) 
    fmt.Printf("Encrypted text : %s\n", b) 
    result, err := decrypt(key, b) 
    if err != nil { 
     log.Fatal(err) 
    } 
    fmt.Printf("Decrypted Text : %s\n", result) 
} 

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(text)) 
    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(text)) 
    return ciphertext, nil 
} 

func decrypt(key []byte, text1 string) ([]byte, error) { 
    text, _ := base64.StdEncoding.DecodeString(string(text1)) 
    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) 
    b := base64.StdEncoding.EncodeToString(text) 
    data, err := base64.StdEncoding.DecodeString(string(b)) 
    if err != nil { 
     return nil, err 
    } 
    return data, nil 
} 

Ausgang: ZVnhCXjIvtGKBdqvjwHRZKcVy34 =

jede Hilfe spürbar sein würde.

+0

* "Aber beide Sprachen funktionieren sollte nicht verschlüsseln/Entschlüsseln Sie den anderen Chiffretext. "* - Bitte geben Sie einige Beispieleingaben und -ausgaben. Ich sehe zumindest einen Unterschied: Es gibt Base64-Kodierung/Dekodierung in Go, aber Hex-Dekodierung in PHP. –

+0

Aktualisierte den Code mit Fix der Hex und Base64 Unterschied und Ausgabe. – Pranav

+0

Nun, weitere Probleme: IV in Go ist '\ 0' gefüllt, aber in PHP' ivusforencrypt'. –

Antwort

1

CFB-Modus ein Problem aufgetreten ist, wird dies im CBC-Modus arbeiten

class Crypto { 
    private $encryptKey = "keyforencryption"; 
    private $iv = "ivusedforencrypt"; 
    private $blocksize = 16; 
    public function encrypt($toEncrypt){ 
     $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC); 
     //$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); 
     return base64_encode($this->iv . mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->encryptKey, $toEncrypt, MCRYPT_MODE_CBC, $this->iv)); 
    } 

    public function decrypt($toDecrypt){ 
     $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);//$this->blocksize; 
     echo "<br/>".$toDecrypt = base64_decode($toDecrypt); 
     return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->encryptKey, substr($toDecrypt, $iv_size), MCRYPT_MODE_CBC, substr($toDecrypt, 0, $iv_size))); 
    } 
} 

$c = new Crypto(); 
echo "Encrypted : ".$e = $c->encrypt("test123"); 
echo "<br/>Decrypted : ".$c->decrypt($e); 

und dieses in golang

package main 

import (
    "crypto/aes" 
    "crypto/cipher" 
    "crypto/rand" 
    "encoding/base64" 
    "fmt" 
    "io" 
    "bytes" 
) 

func main() { 
    e:= cbcEncrypt() 
    fmt.Printf("Encrypted String : %s\n", e) 

    d:= cbcDecrypt(e) 
    fmt.Printf("Decrypted String : %s\n", d) 
} 

func cbcDecrypt(text1 string) []byte{ 
    key := []byte("keyforencryption") 
    ciphertext, _ := base64.StdEncoding.DecodeString(string(text1)) 
    block, err := aes.NewCipher(key) 
    if err != nil { 
     panic(err) 
    } 

    // include it at the beginning of the ciphertext. 
    if len(ciphertext) < aes.BlockSize { 
     panic("ciphertext too short") 
    } 
    iv := ciphertext[:aes.BlockSize] 
    ciphertext = ciphertext[aes.BlockSize:] 

    // CBC mode always works in whole blocks. 
    if len(ciphertext)%aes.BlockSize != 0 { 
     panic("ciphertext is not a multiple of the block size") 
    } 

    mode := cipher.NewCBCDecrypter(block, iv) 

    // CryptBlocks can work in-place if the two arguments are the same. 
    mode.CryptBlocks(ciphertext, ciphertext) 
    ciphertext = PKCS5UnPadding(ciphertext) 
    return ciphertext 
} 

func cbcEncrypt() string{ 
    key := []byte("keyforencryption") 
    plaintext := []byte("testssssss") 
    plaintext = PKCS5Padding(plaintext, 16) 
    // CBC mode works on blocks so plaintexts may need to be padded to the 
    // next whole block. For an example of such padding, see 
    // https://tools.ietf.org/html/rfc5246#section-6.2.3.2. Here we'll 
    // assume that the plaintext is already of the correct length. 
    if len(plaintext)%aes.BlockSize != 0 { 
     panic("plaintext is not a multiple of the block size") 
    } 

    block, err := aes.NewCipher(key) 
    if err != nil { 
     panic(err) 
    } 

    // The IV needs to be unique, but not secure. Therefore it's common to 
    // include it at the beginning of the ciphertext. 
    ciphertext := make([]byte, aes.BlockSize+len(plaintext)) 
    iv := ciphertext[:aes.BlockSize] 
    if _, err := io.ReadFull(rand.Reader, iv); err != nil { 
     panic(err) 
    } 

    mode := cipher.NewCBCEncrypter(block, iv) 
    mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext) 

    // It's important to remember that ciphertexts must be authenticated 
    // (i.e. by using crypto/hmac) as well as being encrypted in order to 
    // be secure. 

    return base64.StdEncoding.EncodeToString(ciphertext) 
} 

func PKCS5Padding(src []byte, blockSize int) []byte { 
    padding := blockSize - len(src)%blockSize 
    padtext := bytes.Repeat([]byte{byte(padding)}, padding) 
    return append(src, padtext...) 
} 

func PKCS5UnPadding(src []byte) []byte { 
    length := len(src) 
    unpadding := int(src[length-1]) 
    return src[:(length - unpadding)] 
} 

dies nicht

+0

Dies führt in meinem Fall immer noch zu anderen Ergebnissen. Ich versuche, dies für die PayTM Gateway-Integration in Go zu verwenden. Hast du irgendwelche Hinweise? –