feat: Implement WinZip AES encryption support in pzip#397
feat: Implement WinZip AES encryption support in pzip#397lzwind merged 3 commits intolinuxdeepin:masterfrom
Conversation
There was a problem hiding this comment.
Sorry @dengzhongyuan365-dev, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
- Added AES encryption options (AES128, AES192, AES256) to the CliPzipPlugin for secure archiving. - Introduced password handling and temporary file management for encryption. - Enhanced the Archiver to support encrypted file writing with WinZip AES format. - Updated command-line interface to include password and encryption method options. - Implemented AES encryption and decryption logic in the AESEncryptor class. - Added WinZip AES extra field handling for ZIP file headers. This feature improves data security during compression and aligns with modern encryption standards. TASK: https://pms.uniontech.com/task-view-388835.html
…hive handling - Introduced a new method `emitProgressIfArchiveGrew` to improve progress reporting during archiving. - Added support for temporary archive creation when dealing with MTP mounted directories. - Updated the command-line interface to include `--ui-events` for better integration with GUI, allowing real-time updates of current file names and progress. - Enhanced the Archiver to handle entry start and byte read events for UI updates. - Improved progress calculation logic to ensure accurate reporting and prevent UI stalls. These changes enhance user experience by providing more responsive feedback during the archiving process. TASK: https://pms.uniontech.com/task-view-388835.html
- Modified the regular expression in Cli7zPlugin to match both "p7zip Version" and "7-Zip" version strings. - This change ensures compatibility with different version outputs, enhancing the plugin's robustness. Improves version detection for better integration with various archive formats. TASK: https://pms.uniontech.com/task-view-388835.html
d6a5d1d to
b75acdd
Compare
deepin pr auto review代码审查报告1. 概述本次代码修改主要实现了以下功能:
2. 语法与逻辑审查2.1 正确部分
2.2 潜在问题2.2.1 加密实现中的潜在问题在 bool AESEncryptor::generateSalt() {
return RAND_bytes(salt_.data(), static_cast<int>(salt_.size())) == 1;
}问题:没有检查 建议: bool AESEncryptor::generateSalt() {
if (RAND_bytes(salt_.data(), static_cast<int>(salt_.size())) != 1) {
lastError_ = "CSPRNG failed: RAND_bytes could not generate salt";
return false;
}
return true;
}2.2.2 进度报告中的潜在问题在 void ProgressPage::calSpeedAndRemainingTime(double &dSpeed, qint64 &qRemainingTime)
{
// ...
if (!m_timer.isValid()) {
m_timer.start();
m_qConsumeTime = 0;
}
const qint64 delta = m_timer.elapsed();
if (delta > 0) {
m_qConsumeTime += delta;
}问题:虽然增加了 建议:确保在 2.2.3 密码处理逻辑中的潜在问题在 static QByteArray passwordBytesLikeLibzipForZip(const QString &strPassword, const QString &archiveName)
{
if (!archiveName.endsWith(QLatin1String(".zip"), Qt::CaseInsensitive)) {
return strPassword.toUtf8();
}
// ...
}问题:密码处理逻辑依赖于文件扩展名判断,如果文件没有 建议:考虑使用 MIME 类型检测而非仅依赖扩展名。 3. 代码质量审查3.1 优点
3.2 改进建议3.2.1 魔法数字在 constexpr uint16_t WINZIP_AES_VERSION_1 = 0x0001; // AE-1
constexpr uint16_t WINZIP_AES_VERSION_2 = 0x0002; // AE-2
constexpr size_t WINZIP_AES_AUTH_CODE_SIZE = 10; // HMAC-SHA1 认证码大小
constexpr size_t WINZIP_AES_PV_SIZE = 2; // 密码验证值大小
constexpr uint32_t PBKDF2_ITERATIONS = 1000; // PBKDF2 迭代次数建议:这些常量定义良好,但建议添加更多注释说明这些值的来源和标准参考。 3.2.2 错误处理在 AESEncryptor::~AESEncryptor() {
if (aesCtx_) {
EVP_CIPHER_CTX_free(aesCtx_);
aesCtx_ = nullptr;
}
if (hmacCtx_) {
HMAC_CTX_free(hmacCtx_);
hmacCtx_ = nullptr;
}
std::fill(aesKey_.begin(), aesKey_.end(), 0);
std::fill(hmacKey_.begin(), hmacKey_.end(), 0);
std::fill(counterBlock_.begin(), counterBlock_.end(), 0);
std::fill(pad_.begin(), pad_.end(), 0);
}优点:析构函数中正确清理了敏感数据(密钥等)。 建议:考虑使用 4. 代码性能审查4.1 优点
4.2 改进建议4.2.1 加密性能在 bool AESEncryptor::aesCrypt(uint8_t* data, size_t length) {
for (size_t i = 0; i < length; i++) {
if (padOffset_ == AES_BLOCK_SIZE) {
incrementCounter();
int outLen = 0;
if (EVP_EncryptUpdate(aesCtx_, pad_.data(), &outLen,
counterBlock_.data(), AES_BLOCK_SIZE) != 1) {
lastError_ = "AES encryption failed";
return false;
}
padOffset_ = 0;
}
data[i] ^= pad_[padOffset_++];
}
return true;
}问题:逐字节处理效率较低。 建议:考虑批量处理数据块,减少循环次数。 4.2.2 进度报告频率在 uint64_t reportedBytesRead = 0;
constexpr uint64_t REPORT_GRANULARITY = 512 * 1024; // 限制回调频率,避免拖慢压缩线程优点:限制了进度报告频率,避免频繁回调影响性能。 建议:考虑将 5. 代码安全审查5.1 优点
5.2 改进建议5.2.1 密码处理在 static QByteArray passwordBytesLikeLibzipForZip(const QString &strPassword, const QString &archiveName)
{
// ...
const QString strUnicode = utf8->toUnicode(strPassword.toUtf8().constData());
return dst->fromUnicode(strUnicode);
}问题:密码处理逻辑复杂,可能引入安全漏洞。 建议:
5.2.2 加密强度在 constexpr uint32_t PBKDF2_ITERATIONS = 1000; // PBKDF2 迭代次数问题:1000 次迭代对于现代硬件可能不够安全。 建议:
5.2.3 临时文件处理在 m_passwordFile = std::make_unique<QTemporaryFile>();
if (!m_passwordFile->open()) {
qWarning() << "Failed to create temporary file for password";
m_eErrorType = ET_PluginError;
return PFT_Error;
}
const QByteArray pwBytes = passwordBytesLikeLibzipForZip(options.strPassword, m_strArchiveName);
if (m_passwordFile->write(pwBytes) != pwBytes.size()) {
qWarning() << "Failed to write password bytes";
m_eErrorType = ET_PluginError;
return PFT_Error;
}问题:密码被写入临时文件,可能被其他进程读取。 建议:
6. 总结6.1 整体评价代码整体质量较高,实现了 WinZip AES 加密功能,并改进了进度报告机制。使用了现代 C++ 特性和安全编程实践。 6.2 主要改进点
6.3 优先级建议
7. 具体修改建议7.1 加密强度改进// 在 src/pzip/include/pzip/common.h 中
constexpr uint32_t PBKDF2_ITERATIONS = 100000; // 增加到 100,000 次7.2 密码处理改进// 在 3rdparty/clipzipplugin/clipzipplugin.cpp 中
static QByteArray passwordBytesLikeLibzipForZip(const QString &strPassword, const QString &archiveName)
{
QByteArray passwordBytes;
// 检查是否为 ZIP 文件
if (!archiveName.endsWith(QLatin1String(".zip"), Qt::CaseInsensitive)) {
passwordBytes = strPassword.toUtf8();
} else {
// 处理 ZIP 文件密码
QTextCodec *utf8 = QTextCodec::codecForName("UTF-8");
if (!utf8) {
passwordBytes = strPassword.toUtf8();
} else {
passwordBytes = utf8->fromUnicode(strPassword);
}
}
// 清除敏感数据
QString::const_iterator it = strPassword.begin();
for (; it != strPassword.end(); ++it) {
// 清除原始密码(Qt 字符串可能无法完全清除)
}
return passwordBytes;
}7.3 加密性能优化// 在 src/pzip/src/crypto/aes_encryptor.cpp 中
bool AESEncryptor::aesCrypt(uint8_t* data, size_t length) {
// 批量处理数据块
while (length > 0) {
if (padOffset_ == AES_BLOCK_SIZE) {
incrementCounter();
int outLen = 0;
if (EVP_EncryptUpdate(aesCtx_, pad_.data(), &outLen,
counterBlock_.data(), AES_BLOCK_SIZE) != 1) {
lastError_ = "AES encryption failed";
return false;
}
padOffset_ = 0;
}
// 计算当前块大小
size_t blockSize = std::min(AES_BLOCK_SIZE - padOffset_, length);
// 批量 XOR
for (size_t i = 0; i < blockSize; i++) {
data[i] ^= pad_[padOffset_++];
}
data += blockSize;
length -= blockSize;
}
return true;
}这些改进将提高代码的安全性、性能和可维护性,同时保持原有功能的完整性。 |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: dengzhongyuan365-dev, lzwind The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
/forcemerge |
feat: Implement WinZip AES encryption support in pzip