I wrote a little test in Kotlin to encrypt some text "Hello" using a Cipher instance with the algorithm "AES/CFB8/NoPadding". (minecraft stuff)
And I am now attempting to do the same in Go, however I am unable to produce the same result. All the different methods I have tried always produce something different.
These are the following threads/examples I've already looked through in order to get to this point.
Kotlin Code:
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)
}
Go Code:
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 code produces the output:
Hello
[68, -97, 26, -50, 126]
[72, 101, 108, 108, 111]
Hello
However, the Go code produces the output:
Hello
[68 97 242 158 187]
[72 101 108 108 111]
Hello
At this point, this issue has pretty much halted the progress of the project I'm working on. Any information on what I'm missing or doing wrong would be helpful.
The solution to this is to implement CFB8 manually since the built in implementation defaults to CFB128.
Implementation created by kostya and fixed by Ilmari Karonen (here).