我有以下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使用的填充方案。
答案 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;
}