11

基本的に AES ECB モード暗号化であるアルゴリズムを Go でエミュレートしようとしています。

これが私がこれまでに持っているものです

func Decrypt(data []byte) []byte {
    cipher, err := aes.NewCipher([]byte(KEY))
    if err == nil {
        cipher.Decrypt(data, PKCS5Pad(data))
        return data
    }
    return nil
}

また、最初にデータをパディングする、テスト済みで機能している PKCS5Padding アルゴリズムもあります。Go AES パッケージで暗号化モードを切り替える方法に関する情報が見つかりません (ドキュメントには絶対にありません)。

このコードは別の言語で作成されているため、このアルゴリズムが正しく機能していないことがわかります。

編集:問題ページから解釈した方法は次のとおりです

func AESECB(ciphertext []byte) []byte {
    cipher, _ := aes.NewCipher([]byte(KEY))
    fmt.Println("AESing the data")
    bs := 16
    if len(ciphertext)%bs != 0     {
        panic("Need a multiple of the blocksize")
    }

    plaintext := make([]byte, len(ciphertext))
    for len(plaintext) > 0 {
        cipher.Decrypt(plaintext, ciphertext)
        plaintext = plaintext[bs:]
        ciphertext = ciphertext[bs:]
    }
    return plaintext
}

これは実際にはデータを返していません。暗号化から復号化に変更するときに何かを台無しにしたのかもしれません

4

5 に答える 5

7

なんで?ECB は意図的に除外しました。これは安全ではなく、必要に応じて簡単に実装できます。

https://github.com/golang/go/issues/5597

于 2014-06-05T23:58:00.620 に答える
4

私はあなたのコードを使用したので、どのように修正したかを示す必要があると感じています.

Go でこの問題のクリプトパル チャレンジを行っています。

コードはほとんど正しいので、間違いについて説明します。

for len(plaintext) > 0 {
    cipher.Decrypt(plaintext, ciphertext)
    plaintext = plaintext[bs:]
    ciphertext = ciphertext[bs:]
}

ループはデータを復号化しますが、どこにも置きません。2 つの配列をシフトするだけで、出力は生成されません。

i := 0
plaintext := make([]byte, len(ciphertext))
finalplaintext := make([]byte, len(ciphertext))
for len(ciphertext) > 0 {
    cipher.Decrypt(plaintext, ciphertext)
    ciphertext = ciphertext[bs:]
    decryptedBlock := plaintext[:bs]
    for index, element := range decryptedBlock {
        finalplaintext[(i*bs)+index] = element
    }
    i++
    plaintext = plaintext[bs:]
} 
return finalplaintext[:len(finalplaintext)-5]

この新しい改良点は、復号化されたデータを finalplaintext と呼ばれる新しい [] バイトに格納することです。それを返すと、データが取得されます。

Decrypt 関数は一度に 1 つのブロック サイズしか機能しないため、このようにすることが重要です。

パディングされていると思われるため、スライスを返します。私は暗号化と Go を初めて使用するので、誰でも自由に修正/修正してください。

于 2016-05-15T23:42:38.963 に答える
1

crypto/cipher#BlockModeインターフェイスを実装するのが理想的です。公式のものは存在しないので、私はcrypto/cipher#NewCB​​CEncrypterを出発点として使用しました:

package ecb
import "crypto/cipher"

type ecbEncrypter struct { cipher.Block }

func newECBEncrypter(b cipher.Block) cipher.BlockMode {
   return ecbEncrypter{b}
}

func (x ecbEncrypter) BlockSize() int {
   return x.Block.BlockSize()
}

func (x ecbEncrypter) CryptBlocks(dst, src []byte) {
   size := x.BlockSize()
   if len(src) % size != 0 {
      panic("crypto/cipher: input not full blocks")
   }
   if len(dst) < len(src) {
      panic("crypto/cipher: output smaller than input")
   }
   for len(src) > 0 {
      x.Encrypt(dst, src)
      src, dst = src[size:], dst[size:]
   }
}
于 2021-03-07T02:03:01.730 に答える