Crypto ++相当于PHP mcrypt_encrypt MCRYPT_3DES / MCRYPT_MODE_CBC

时间:2016-10-10 17:45:12

标签: php c++ crypto++ 3des

我有以下PHP代码使用密钥加密文本:

class Manga(models.Model):
    COMPLETED = 'COMP'
    ONGOING = 'ONG'
    STATUS_CHOICES = (
        (COMPLETED, 'Completed'),
        (ONGOING, 'Ongoing'),
    )
    JAPANESE_MANGA = 'JM'
    KOREAN_MANGA = 'KM'
    CHINESE_MANGA = 'CM'
    UNKNOWN_MANGA = 'UM'
    TYPE_CHOICES = (
        (JAPANESE_MANGA, 'Japanese Manga'),
        (KOREAN_MANGA, 'Korean Manhwa'),
        (CHINESE_MANGA, 'Chinese Manhua'),
        (UNKNOWN_MANGA, 'Unknown'),
    )
    authors = models.ManyToManyField(Author)
    genres = models.ManyToManyField(Genre)
    name = models.CharField(max_length=255, default="")
    image = models.ImageField(upload_to=upload_manga_cover)
    summary = models.TextField(max_length=1000)
    rating = models.IntegerField(default=0)
    views = models.IntegerField(default=0)
    rank = models.IntegerField(default=0)
    alt_names = models.TextField(max_length=400, default="")
    type = models.CharField(
        max_length=255,
        choices=TYPE_CHOICES,
        default=UNKNOWN_MANGA
    )
    status = models.CharField(
        max_length=255,
        choices=STATUS_CHOICES,
        default=ONGOING,
    )
    released = models.DateField()
    date_added = models.DateTimeField(auto_now_add=True)
    date_modified = models.DateTimeField(auto_now=True)
    slug = models.SlugField(unique=True)

    def __str__(self):
        return self.name

我使用Crypto ++的相应C ++函数是:

function des_ed3_crypt($msg, $key) {
   $bytes = array(0,0,0,0,0,0,0,0);
   $iv=implode(array_map('chr', $bytes));

   return mcrypt_encrypt(MCRYPT_3DES, $key, $msg, MCRYPT_MODE_CBC, $iv);
}

但他们不会返回相同的加密文本。我希望将C ++代码更改为等同于PHP代码,而不是相反。

对于以下密钥和消息:

std::string des_ed3_crypt(std::string const& msg, std::string const& key)
{
    unsigned char iv[8] = { 0 }; // 0-filled

    CryptoPP::CBC_Mode<CryptoPP::DES_EDE3>::Encryption e;
    e.SetKeyWithIV(reinterpret_cast<unsigned char const*>(key.c_str()),
                   key.size(), iv);

    std::string ret;

    CryptoPP::StringSource(msg, true,
            new CryptoPP::StreamTransformationFilter
                 (e, new CryptoPP::StringSink(ret)));

    return ret;
}

PHP代码返回24字节的密文(base64编码为):

$key = "keykeykeykeykeykeykeykey";
$msg = $key;

但是C ++返回一个32字节的密文,但匹配前缀为24字节(base64编码为):

a78URfI6EV8m3sTaDDDrntI8VbjWHiwm

所以,C ++版本中还有一些额外的字节,我不知道它们来自哪里。我认为它可能与填充方案有关,但我不知道PHP使用的填充方案。

1 个答案:

答案 0 :(得分:1)

实际上,它是填充物。 PHP mcrypt_crypto函数应用零填充,因此,我只需要指定cryptopp我要对加密应用零填充:

std::string des_ed3_crypt(std::string const& msg, std::string const& key)
{
    unsigned char iv[8] = { 0 }; // 0-filled

    CryptoPP::CBC_Mode<CryptoPP::DES_EDE3>::Encryption e;
    e.SetKeyWithIV(reinterpret_cast<unsigned char const*>(key.c_str()),
                   key.size(), iv);

    std::string ret;

    CryptoPP::StringSource(msg, true,
        new CryptoPP::StreamTransformationFilter
            (e, new CryptoPP::StringSink(ret),
             CryptoPP::BlockPaddingSchemeDef::BlockPaddingScheme::ZEROS_PADDING));

    return ret;
}