0

RFC 4880 第 50 页的底部描述了如何加密明文数据以存储在对称加密完整性保护数据包(标签 18)中。它说使用了CFB模式。我已经为 CFB 编写了代码,以便它按照第 13.9 节中的描述工作(对于对称加密数据包(标签 9))。但是,在第 50 页,它还说:

与对称加密数据包不同,在加密此前缀数据后不进行特殊的 CFB 重新同步。

因此,对于标签 18,步骤应如下所示:

一步一步来,流程如下:

  1. 反馈寄存器 (FR) 设置为 IV,即全为零。

  2. FR被加密产生FRE(FR Encrypted)。这是全零值的加密。

  3. FRE 与以明文为前缀的随机数据的第一个 BS 八位字节进行异或运算,以产生 C 1到 C[BS],即密文的第一个 BS 八位字节。

  4. FR通过C[BS]加载C[ 1 ]。

  5. FR 被加密以产生 FRE,即密文的第一个 BS 八位字节的加密。

  6. FRE 的左两个八位字节与作为明文前缀的接下来的两个八位字节数据进行异或运算。这将产生 C[BS+1] 和 C[BS+2],即接下来的两个八位字节的密文。

  7. (̶T̶h̶e̶̶r̶e̶s̶y̶n̶c̶h̶r̶o̶n̶i̶z̶a̶t̶i̶o̶n̶̶s̶t̶e̶p̶)̶̶F̶R̶̶i̶s̶̶l̶o̶a̶d̶e̶d̶̶w̶i̶t̶h̶̶C̶[̶3̶]̶t̶h̶r̶o̶u̶g̶h̶C̶[̶B̶S+

  8. FR被加密产生—FRE

  9. FRE 与给定明文的第一个 BS 八位字节进行异或运算,现在我们已经完成了对前缀数据的 BS+2 个八位字节的加密。这会产生 C[BS+3] 到 C[BS+(BS+2)],即密文的下一个 BS 八位字节。

  10. FR 加载了 C[BS+3] 到 C[BS + (BS+2)](对于 8 字节块来说是 C11-C18)。

    1. FR被加密以产生FRE。

    2. FRE 与明文的下一个 BS 八位字节进行异或运算,以产生密文的下一个 BS 八位字节。这些被加载到 FR 中,并重复该过程,直到明文用完。

由于重新同步步骤没有做,步骤8使用步骤5的FRE,所以可以忽略吧?

从上述步骤中,我在以下代码中误解了什么?我知道它适用于标签 9,带有重新同步步骤,但标签 18 并没有加起来。

std::string CFB_encrypt(SymAlg * crypt, uint8_t packet, std::string data, std::string prefix){
    uint8_t BS = crypt -> blocksize() >> 3;
    // 1
    std::string IV(BS, 0);
    // 2
    std::string FR = IV;
    std::string FRE = crypt -> encrypt(FR);
    // 3
    FRE = xor_strings(FRE, prefix);
    std::string C = FRE;
    // 4
    FR = C;
    // 5
    FRE = crypt -> encrypt(FR);
    // 6
    C += xor_strings(FRE.substr(0, 2), prefix.substr(BS - 2, 2));
    // 7
    if (packet == 9){
        FR = C.substr(2, BS);
    }
    // 8
    FRE = crypt -> encrypt(FR);
    // 9
    C += xor_strings(FRE, data.substr(0, BS));
    unsigned int x = BS;
    while (x < data.size()){
        // 10
        FR = C.substr(x + 2, BS);
        // 11
        FRE = crypt -> encrypt(FR);
        // 12
        C += xor_strings(FRE, data.substr(x, BS));
        x += BS;
    }
    return C;
}

我错过了什么?

4

2 回答 2

1

您的第 3 步:

3. FRE is xored with the first BS octets of random data prefixed to the plaintext

与您的代码不匹配:

// 3
std::string C = FRE;

这里没有xoring。尝试将其更改为:

std::string C = xor_strings(FRE, prefix.substr(0,8));
于 2013-08-14T21:09:12.587 回答
0

这段代码以某种方式起作用。我不明白:

    else {
        plaintext = "  "+plaintext;
        // 9.  FRE is xored with the first 8 octets of the given plaintext, now
        //     that we have finished encrypting the 10 octets of prefixed data.
        //     This produces C11-C18, the next 8 octets of ciphertext.
        for (var i = 2; i &lt; block_size; i++) ciphertext += String.fromCharCode(FRE[i] ^ plaintext.charCodeAt(i));
        var tempCiphertext = ciphertext.substring(0,2*block_size).split('');
        var tempCiphertextString = ciphertext.substring(block_size);
        for(n=block_size; n&lt;plaintext.length; n+=block_size) {
            // 10. FR is loaded with C11-C18
            for (var i = 0; i &lt; block_size; i++) FR[i] = tempCiphertextString.charCodeAt(i);
            tempCiphertextString='';

            // 11. FR is encrypted to produce FRE.
            FRE = blockcipherencryptfn(FR, key);

            // 12. FRE is xored with the next 8 octets of plaintext, to produce the
            //     next 8 octets of ciphertext.  These are loaded into FR and the
            //     process is repeated until the plaintext is used up.
            for (var i = 0; i &lt; block_size; i++){ tempCiphertext.push(String.fromCharCode(FRE[i] ^ plaintext.charCodeAt(n+i)));
            tempCiphertextString += String.fromCharCode(FRE[i] ^ plaintext.charCodeAt(n+i));
            }
        }
        ciphertext = tempCiphertext.join('');

    }
    return ciphertext;
}
于 2013-08-15T21:05:15.547 回答