Tag18的OpenPGP CFB模式

时间:2013-08-14 17:58:24

标签: c++ encryption implementation openpgp

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

  

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

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

  

一步一步,这是程序:

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

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

  4.   
  5. FRE用前缀为的随机数据的第一个BS八位字节进行过滤      明文产生C 1到C [BS],第一个BS八位字节      密文。

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

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

  10.   
  11. FRE的左边两个八位字节用接下来的两个八位字节得到xored      以明文为前缀的数据。这产生C [BS + 1]      和C [BS + 2],密文的下两个八位字节。

  12.   
  13. (̶T̶h̶e̶̶r̶e̶s̶y̶n̶c̶h̶r̶o̶n̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶      C [BS + 2]

  14.   
  15. FR已加密生成̶FRE

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

  18.   
  19. FR加载C [BS + 3]至C [BS +(BS + 2)](C11-C18为      一个8个八位字节的块。)

         
        
    1. FR已加密以产生FRE。

    2.   
    3. FRE用下一个明文的BS八位字节进行编码,以产生   密文的下一个BS八位字节。这些被加载到FR,和   重复该过程,直到明文用完为止。

    4.   
  20.   

由于重新同步步骤未完成,步骤8使用步骤5的FRE,因此可以忽略它吗?

从上面的步骤,我在下面的代码中误解了什么?我知道它适用于Tag 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;
}

我错过了什么?

2 个答案:

答案 0 :(得分: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));

答案 1 :(得分:0)

This chunk of code不知何故有效。我不明白:

    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;
}