如何在 Go 中正确编写 JVM AES/CFB8 加密

How to properly write JVM AES/CFB8 Encryption in Go

我在 Kotlin 中写了一个小测试来加密一些文本 "Hello" 使用 Cipher 实例和算法 "AES/CFB8/NoPadding"。 (我的世界的东西)

我现在正尝试在 Go 中做同样的事情,但是我无法产生相同的结果。我尝试过的所有不同方法总是产生不同的结果。

这些是以下 threads/examples 为了达到这一点,我已经浏览过。

  1. https://play.golang.org/p/77fRvrDa4A
  2. https://gist.github.com/temoto/5052503
  3. AES Encryption in Golang and Decryption in Java
  4. Different Results in Go and Pycrypto when using AES-CFB

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 创建并由 Ilmari Karonen (here) 修复的实现。