我在Kotlin中编写了一个小测试,以使用带有算法“ AES / CFB8 / NoPadding”的Cipher实例加密一些文本“ Hello”。(Minecraft的东西)
我现在正尝试在Go中执行相同的操作,但是我无法产生相同的结果。我尝试过的所有不同方法都会产生不同的结果。
这些是我已经浏览过的以下线程/示例,以达到这一点。
Kotlin代码:
enum class Mode(val mode: Int) { ENCRYPT(Cipher.ENCRYPT_MODE), DECRYPT(Cipher.DECRYPT_MODE), } fun createSecret(data: String): SecretKey { return SecretKeySpec(data.toByteArray(), "AES") } fun newCipher(mode: Mode): Cipher { val secret = createSecret("qwdhyte62kjneThg") val cipher = Cipher.getInstance("AES/CFB8/NoPadding") cipher.init(mode.mode, secret, IvParameterSpec(secret.encoded)) return cipher } fun runCipher(data: ByteArray, cipher: Cipher): ByteArray { val output = ByteArray(data.size) cipher.update(data, 0, data.size, output) return output } fun main() { val encrypter = newCipher(Mode.ENCRYPT) val decrypter = newCipher(Mode.DECRYPT) val iText = "Hello" val eText = runCipher(iText.toByteArray(), encrypter) val dText = runCipher(eText, decrypter) val oText = String(dText) println(iText) println(Arrays.toString(eText)) println(Arrays.toString(dText)) println(oText) }
验证码:
func TestCipher(t *testing.T) { secret := newSecret("qwdhyte62kjneThg") encrypter := newCipher(secret, ENCRYPT) decrypter := newCipher(secret, DECRYPT) iText := "Hello" eText := encrypter.run([]byte(iText)) dText := decrypter.run(eText) oText := string(dText) fmt.Printf("%s\n%v\n%v\n%s\n", iText, eText, dText, oText) } type Mode int const ( ENCRYPT Mode = iota DECRYPT ) type secret struct { Data []byte } type cipherInst struct { Data cipher2.Block Make cipher2.Stream } func newSecret(text string) *secret { return &secret{Data: []byte(text)} } func newCipher(data *secret, mode Mode) *cipherInst { cip, err := aes.NewCipher(data.Data) if err != nil { panic(err) } var stream cipher2.Stream if mode == ENCRYPT { stream = cipher2.NewCFBEncrypter(cip, data.Data) } else { stream = cipher2.NewCFBDecrypter(cip, data.Data) } return &cipherInst{Data: cip, Make: stream} } func (cipher *cipherInst) run(dataI []byte) []byte { out := make([]byte, len(dataI)) cipher.Make.XORKeyStream(out, dataI) return out }
Kotlin代码产生输出:
Hello [68, -97, 26, -50, 126] [72, 101, 108, 108, 111] Hello
但是,Go代码会产生输出:
Hello [68 97 242 158 187] [72 101 108 108 111] Hello
在这一点上,这个问题已经使我正在从事的项目的进度几乎停止了。关于我所缺少或做错的任何信息都将有所帮助。
解决方案是手动实施CFB8,因为内置实施默认为CFB128。
由kostya创建并由IlmariKaronen修复的实现。
如果有人正在寻找分段大小= 8的Go实现CFB模式,则可以使用以下方法:
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 }