Dan*_*ler 10 python encryption go pycrypto
我在现有的python代码库中添加了一个go应用程序.我在处理语言之间的加密方面遇到了麻烦.这是使用go 1.2.1和Python 2.7.x/PyCrypto 2.7a1.
这是Python示例:
import Crypto.Cipher
import Crypto.Hash.HMAC
import Crypto.Hash.SHA256
import Crypto.PublicKey.RSA
from binascii import hexlify, unhexlify
#encrypt
payload = unhexlify("abababababababababababababababababababababababababababababababab")
password = unhexlify("0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF")
iv = unhexlify("00000000000000000000000000000000")
print "IV: ", hexlify(iv), "len: ", len(iv)
print "Password length: ", len(password)
cipher = Crypto.Cipher.AES.new(
key=password,
mode=Crypto.Cipher.AES.MODE_CFB,
IV=iv)
payload = cipher.encrypt(payload)
print hexlify(payload) #dbf6b1877ba903330cb9cf0c4f530d40bf77fe2bf505820e993741c7f698ad6b
Run Code Online (Sandbox Code Playgroud)
这是Go示例:
package main
import (
"fmt"
"crypto/cipher"
"crypto/aes"
"encoding/hex"
)
// encrypt
func main() {
payload, err1 := hex.DecodeString("abababababababababababababababababababababababababababababababab")
password, err2 := hex.DecodeString("0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF")
iv, err3 := hex.DecodeString("00000000000000000000000000000000")
if err1 != nil {
fmt.Printf("error 1: %v", err1)
return
}
if err2 != nil {
fmt.Printf("error 2: %v", err2)
return
}
if err3 != nil {
fmt.Printf("error 3: %v", err3)
return
}
aesBlock, err4 := aes.NewCipher(password)
fmt.Printf("IV length:%v\n", len(iv))
fmt.Printf("password length:%v\n", len(password))
if err4 != nil {
fmt.Printf("error 4: %v", err4)
return
}
cfbDecrypter := cipher.NewCFBEncrypter(aesBlock, iv)
cfbDecrypter.XORKeyStream(payload, payload)
fmt.Printf("%v\n", hex.EncodeToString(payload)) // db70cd9e6904359cb848410bfa38d7d0a47b594f7eff72d547d3772c9d4f5dbe
}
Run Code Online (Sandbox Code Playgroud)
这是golang链接,我找不到安装了PyCrypto的Python pastebin.
根据标题和来源的建议,这两个片段产生不同的密文:
Python:dbf6b1877ba903330cb9cf0c4f530d40bf77fe2bf505820e993741c7f698ad6b
Golang:db70cd9e6904359cb848410bfa38d7d0a47b594f7eff72d547d3772c9d4f5dbe
两种语言都可以解密他们的"原生"cypthertext,但两种语言都不能解密其他语言.因为python实现已经存在,所以我正在寻找一种解决方案,允许Go解密使用示例PyCrypto AES设置和密钥大小加密的密文.
Dan*_*ler 10
对当前系统的研究表明,我们的python系统使用CFB8(8位段).Go不支持开箱即用,但当前CFBDecrypter/CFBEncrypter中使用的源代码看起来很容易适应.
如果有人正在寻找段大小 = 8 的 CFB 模式的 Go 实现,您可以使用以下命令:
import "crypto/cipher"
// CFB stream with 8 bit segment size
// See http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
type cfb8 struct {
b cipher.Block
blockSize int
in []byte
out []byte
decrypt bool
}
func (x *cfb8) XORKeyStream(dst, src []byte) {
for i := range src {
x.b.Encrypt(x.out, x.in)
copy(x.in[:x.blockSize-1], x.in[1:])
if x.decrypt {
x.in[x.blockSize-1] = src[i]
}
dst[i] = src[i] ^ x.out[0]
if !x.decrypt {
x.in[x.blockSize-1] = dst[i]
}
}
}
// NewCFB8Encrypter returns a Stream which encrypts with cipher feedback mode
// (segment size = 8), using the given Block. The iv must be the same length as
// the Block's block size.
func newCFB8Encrypter(block cipher.Block, iv []byte) cipher.Stream {
return newCFB8(block, iv, false)
}
// NewCFB8Decrypter returns a Stream which decrypts with cipher feedback mode
// (segment size = 8), using the given Block. The iv must be the same length as
// the Block's block size.
func newCFB8Decrypter(block cipher.Block, iv []byte) cipher.Stream {
return newCFB8(block, iv, true)
}
func newCFB8(block cipher.Block, iv []byte, decrypt bool) cipher.Stream {
blockSize := block.BlockSize()
if len(iv) != blockSize {
// stack trace will indicate whether it was de or encryption
panic("cipher.newCFB: IV length must equal block size")
}
x := &cfb8{
b: block,
blockSize: blockSize,
out: make([]byte, blockSize),
in: make([]byte, blockSize),
decrypt: decrypt,
}
copy(x.in, iv)
return x
}
Run Code Online (Sandbox Code Playgroud)
小智 6
看来,密码可以进行兼容Go的加密/密码,如果我们改变segment_size的AES从默认的对象8来AES.block_size*8(这是128),就像这样:
Crypto.Cipher.AES.new(
key=password,
mode=Crypto.Cipher.AES.MODE_CFB,
IV=iv,
segment_size=AES.block_size*8
)
Run Code Online (Sandbox Code Playgroud)