gene / module-encryption-key-manager
基因加密密钥管理器
Requires
- php: ^8.1||^8.2||^8.3
- magento/module-catalog: *
- magento/module-encryption-key: *
- magento/module-jwt-user-token: *
- dev-master
- v0.0.15-alpha
- v0.0.14-alpha
- v0.0.13-alpha
- v0.0.12-alpha
- v0.0.11-alpha
- v0.0.10-alpha
- v0.0.9-alpha
- v0.0.8-alpha
- v0.0.7-alpha
- v0.0.6-alpha
- v0.0.5-alpha
- v0.0.4-alpha
- v0.0.3-alpha
- v0.0.2-alpha
- v0.0.1-alpha
- dev-PHP7.4-compat
- dev-feature/get-cloud-env-keys
- dev-performance-improvements-large
- dev-performance-improvements-baseline
- dev-performance-improvements
- dev-patch-1
- dev-pull-request-25
This package is auto-updated.
Last update: 2024-09-20 08:27:27 UTC
README
此模块是为了帮助应对 https://sansec.io/research/cosmicsting-hitting-major-stores
来自 sansec 的帖子
升级不足:正如我们之前文章中所警告的,商家升级或应用官方隔离修复至关重要。然而,在此阶段,仅修复 CosmicSting 漏洞可能是不够的。
被盗的加密密钥仍然允许攻击者在升级后生成网络令牌。目前仍然容易受到攻击的商家应将其加密密钥视为已泄露。Adobe 提供了更改加密密钥的功能,同时重新加密现有秘密。
重要提示:使用此功能生成新的加密密钥不会使旧密钥失效。我们建议手动在 app/etc/env.php 中将旧密钥更新为新值,而不是删除它。
即使您的商店已得到保护,也有可能已发布了 JWT,并且它可能仍然有效。强烈建议商家更换加密密钥以确保安全,而 Magento 生成新加密密钥的过程实际上并不会使旧密钥失效。
本模块按原样提供,不提供任何保证。请在本地实例上测试此模块,然后是测试环境,最后是生产环境。自行承担风险使用。
此模块 不会与 Adobe 发布的 新热修复 冲突。本模块和该热修复都以相同的方式提高安全性,即通过使 SecretBasedJwksFactory
使用最新的密钥。此模块还提供了额外的工具和改进,请参阅以下内容。
安装
composer require gene/module-encryption-key-manager
bin/magento setup:upgrade
如何旋转密钥并保护您的商店
以下是一个大致步骤列表,应遵循以防止 CosmicSting 攻击。请仔细阅读所有步骤,以了解此模块提供的功能以及风险点。
生成新密钥并防止旧密钥用于 JWT
这应该是每个商家的 首要任务! 安装此模块并使用以下命令生成新密钥:
php bin/magento gene:encryption-key-manager:generate [--key=MY_32_CHAR_CRYPT_KEY] [--skip-saved-credit-cards]
这将强制 JWT 工厂使用新生成的密钥。应用程序的其他部分可能继续使用旧密钥。此步骤是绝对首要的,并将有助于防止 CosmicSting 攻击。
- 使用
--key
选项手动定义重新加密期间使用的密钥。如果没有提供自定义密钥,则将生成新密钥。 - 使用
--skip-saved-credit-cards
标志跳过重新加密sales_order_payment
cc_number_enc
数据。此表可能非常大,许多商店在此列中可能没有任何数据保存。
完全旋转旧密钥
您可以根据需要完成以下操作。只要您已安装独立补丁并使用此模块生成新的加密密钥,您就安全免受cosmicsting的威胁。
然后您可以自由决定是否要重新加密旧数据,并使旧密钥无效。
- 审查数据库(确保zgrep版本为1.12)中具有加密值的任何表。请确保您的转储设置为
--human-readable
(magerun)或--extended-insert=FALSE
(mysqldump),以便所有值都位于与INSERT INTO
相同的行上。
$ zgrep -P "VALUES\s*\(.*\d:\d:...*'" database.sql | awk '{print $3}' | uniq admin_user core_config_data customer_entity oauth_token oauth_consumer tfa_user_config admin_adobe_ims_webapi adobe_user_profile
或获取所有找到的表及其记录数的概览。
zgrep -P "VALUES\s*\(.*\d:\d:...*'" database.sql | awk '{print $3}' | sort | uniq -c
- 审查
env.php
,如果您在那里存储任何加密值,它们可能已被泄露,需要提供商重新发布。 - 审查使用加密类中的
->hash(
)函数的functions
。更改密钥将导致不同的哈希值。 - 如果您有处理此问题的
custom logic
,则需要手动解决。 - 生成新的密钥
php bin/magento gene:encryption-key-manager:generate
- 您可以使用
php bin/magento gene:encryption-key-manager:generate --key=MY_32_CHAR_CRYPT_KEY
指定要使用的新加密密钥。 Magento\Catalog\Model\View\Asset\Image
将继续在索引0
处使用密钥。Magento\JwtUserToken\Model\SecretBasedJwksFactory
将只使用最新生成的密钥,索引最高。
- 您可以使用
- 修复缺失的配置值
php bin/magento gene:encryption-key-manager:reencrypt-unhandled-core-config-data
- 重新运行以验证
php bin/magento gene:encryption-key-manager:reencrypt-unhandled-core-config-data
- 重新运行以验证
- 修复双因素认证数据
php bin/magento gene:encryption-key-manager:reencrypt-tfa-data
- 重新运行以验证
php bin/magento gene:encryption-key-manager:reencrypt-tfa-data
- 重新运行以验证
- 修复所有其他已识别的列,例如,请务必验证每个表和列,因为这可能不是完整的列表(还要注意
entity_id
、row_id
和id
)php bin/magento gene:encryption-key-manager:reencrypt-column admin_user user_id rp_token
php bin/magento gene:encryption-key-manager:reencrypt-column customer_entity entity_id rp_token
php bin/magento gene:encryption-key-manager:reencrypt-column oauth_token entity_id secret
php bin/magento gene:encryption-key-manager:reencrypt-column oauth_consumer entity_id secret
php bin/magento gene:encryption-key-manager:reencrypt-column admin_adobe_ims_webapi id access_token
php bin/magento gene:encryption-key-manager:reencrypt-column adobe_user_profile id access_token
- 刷新缓存
php bin/magento cache:flush
- 此时,您应该已将所有数据迁移到新的加密密钥,为了帮助您验证这一点,您可以执行以下操作
php bin/magento config:set --lock-env dev/debug/gene_encryption_manager_only_log_old_decrypts 1
php bin/magento config:set --lock-env dev/debug/gene_encryption_manager_enable_decrypt_logging 1
- 监控您的日志以查找“gene encryption manager”,以验证是否仍有任何内容仍在使用旧密钥
- 当您满意时,可以
使旧密钥无效
php bin/magento gene:encryption-key-manager:invalidate
Magento\Catalog\Model\View\Asset\Image
将继续在crypt/invalidated_key
部分的索引0
处使用密钥。
- 测试,测试,测试!您的测试重点包括
- 使用Magento的API的所有集成
- 您的媒体应该仍然以相同的哈希目录显示。如果它正在重新生成,它将占用大量的磁盘空间和运行时间。
- 管理员用户登录/注销
- 客户登录/注销
功能
在生成新密钥时自动使旧JWT无效
当magento生成新加密密钥时,它仍然允许使用JWT使用旧密钥。本模块通过更新\Magento\JwtUserToken\Model\SecretBasedJwksFactory
来阻止这一点,以仅允许针对最新加密密钥生成的密钥。
我们注入了一个包装的\Gene\EncryptionKeyManager\Model\DeploymentConfig
,它只返回最新的加密密钥。这意味着当生成新加密密钥时,任何现有令牌都不再可使用。
允许您保留现有的媒体缓存目录
当magento生成新的加密密钥时,会导致产品媒体缓存哈希值改变。这会导致所有产品媒体重新生成,消耗大量处理时间,可能会减慢顾客的页面加载速度,同时也消耗额外的磁盘空间。本模块确保媒体库仍然使用旧哈希值。
Magento将调整大小后的产品图像存储在如media/catalog/product/cache/abc123/f/o/foobar.jpg
这样的目录中,哈希值abc123
是通过系统中的加密密钥生成的。
为了避免在循环加密密钥时需要重新生成所有产品媒体,这里有一些更改以强制继续使用原始值。
Magento\Catalog\Model\View\Asset\Image
将$encryptor
替换为Gene\EncryptionKeyManager\Service\InvalidatedKeyHasher
。这使得您可以使用旧密钥继续生成md5哈希值。
防止长时间运行的过程更新订单付款
此模块还将修复一个问题,即在密钥生成过程中会更新每个sales_order_payment
条目。在大型商店中,这可能需要很长时间。现在,只有包含已保存卡片信息的必要条目才会更新。
日志记录
本模块提供了一种机制来记录每次解密调用的来源。由于magento系统配置被加密,因此每个请求都会触发日志写入,因此这将产生大量数据。
建议在您处理了系统中所有数据的重新加密之后启用此日志记录,但在使旧密钥无效之前。
这将向您提供一个指示,表明您已经妥善处理了一切,因为如果看到日志被写入,它将告诉您有什么被遗漏以及如何找到问题的来源。
php bin/magento config:set --lock-env dev/debug/gene_encryption_manager_only_log_old_decrypts 1 php bin/magento config:set --lock-env dev/debug/gene_encryption_manager_enable_decrypt_logging 1
日志文件位于 <mage_dir>/var/log/gene_encryption_key.log
bin/magento gene:encryption-key-manager:generate
您可以使用php bin/magento gene:encryption-key-manager:generate
来生成新的加密密钥
此CLI工具执行与\Magento\EncryptionKey\Controller\Adminhtml\Crypt\Key\Save::execute()
相同的任务,但进行了一些调整
- 避免不必要的操作空
sales_order_payment
cc_number_enc
值。这在大型商店中很有帮助,其中此表包含许多条目。
$ php bin/magento gene:encryption-key-manager:generate --force Generating a new encryption key _reEncryptSystemConfigurationValues - start _reEncryptSystemConfigurationValues - end _reEncryptCreditCardNumbers - start _reEncryptCreditCardNumbers - end Cleaning cache Done
- 使用
--key
选项手动定义重新加密期间使用的密钥。如果没有提供自定义密钥,则将生成新密钥。 - 使用
--skip-saved-credit-cards
标志跳过重新加密sales_order_payment
cc_number_enc
数据。此表可能非常大,许多商店在此列中可能没有任何数据保存。 - 这将自动重新加密
app/etc/env.php
中所有system
值。
bin/magento gene:encryption-key-manager:invalidate
您可以使用php bin/magento gene:encryption-key-manager:invalidate
来使旧密钥无效
这将创建一个新的部分来存储env.php
中的旧invalidated_key
,以及将crypt/key
路径用无意义文本替换,以保持密钥的数值顺序。
在使无效之前
'crypt' => [ 'key' => '84c9d7c0b305adf9ea7e19a05478bf11 2951b41e2b7f4c26e60a8e7ee00ca17b' ],
在使无效之后
'crypt' => [ 'key' => 'invalidpwecbVeGpoL3Jxa4PXEOdn1ej 2951b41e2b7f4c26e60a8e7ee00ca17b', 'invalidated_key' => '84c9d7c0b305adf9ea7e19a05478bf11' ],
bin/magento gene:encryption-key-manager:reencrypt-unhandled-core-config-data
当magento生成新的加密密钥时,它会重新加密core_config_data
中定义的backend_model
为Magento\Config\Model\Config\Backend\Encrypted
的值。可能某些第三方模块没有正确实现此功能并自行处理了解密。在这些情况下,我们需要强制通过重新加密过程。
默认情况下,此命令以dry run模式运行,作为第一次运行,以查看将要进行的更改。当您满意时,使用--force
运行。
$ php bin/magento gene:encryption-key-manager:reencrypt-unhandled-core-config-data Run with --force to make these changes, this will run in dry-run mode by default The latest encryption key is number 14, looking for old entries ################################################################################ config_id: 1347 scope: default scope_id: 0 path: yotpo/settings/secret updated_at: 2023-08-31 12:48:27 ciphertext_old: 0:2:abc123 plaintext: some_secret_here ciphertext_new: 14:3:xyz456 Dry run mode, no changes have been made ################################################################################ Done
bin/magento gene:encryption-key-manager:reencrypt-column
这允许您针对特定列进行重新加密。如果列包含JSON,您可以使用点表示法:column.field
。
默认情况下,此命令以dry run模式运行,作为第一次运行,以查看将要进行的更改。当您满意时,使用--force
运行。
您应确定所有需要处理的列,并通过此过程运行它们。
$ bin/magento gene:encryption-key-manager:reencrypt-column customer_entity entity_id rp_token Run with --force to make these changes, this will run in dry-run mode by default The latest encryption key is number 1, looking for old entries Looking for 'rp_token' in 'customer_entity', identified by 'entity_id' ######################################################################################################################## entity_id: 9876 ciphertext_old: 0:3:54+QHWqhSwuncAa87Ueph7xF9qPL1CT6+M9Z5AWuup447J33KGVw+Q+BvVLSKR1H1umiq69phKq5NEHk plaintext: acb123 ciphertext_new: 1:3:Y52lxB2VDnKeOHa0hf7kG/d15oooib6GQOYTcAmzfuEnhfW64NAdNN4YjRrhlh2IzQBO5IbwS48JDDRh Dry run mode, no changes have been made ######################################################################################################################## Done
bin/magento gene:encryption-key-manager:reencrypt-tfa-data
此命令重新加密存储在tfa_user_config
中的2FA数据。其中一些数据是双重加密的,因此需要特殊处理。
默认情况下,此命令以dry run模式运行,作为第一次运行,以查看将要进行的更改。当您满意时,使用--force
运行。
此CLI工具仅在Google Authenticator (TOTP)和U2F (Yubikey等)上进行测试。如果您使用Authy或DUO,您必须在使用前进行验证。
$ bin/magento gene:encryption-key-manager:reencrypt-tfa-data Run with --force to make these changes, this will run in dry-run mode by default This CLI has only been tested with Google Authenticator (TOTP) and U2F (Yubikey, etc). If you use Authy or DUO you *MUST* verify before use. The latest encryption key is number 1, looking for old entries Looking for encoded_config in tfa_user_config, identified by 'config_id' ######################################################################################################################## config_id: 1 ciphertext_old: 0:3:rV/z9+ilmOtaPGnOoZBayZ3waBNphK1RAcyWLetipM5UONn793rTyRknO1GhWxKxXC3ooJAgWDTMJPaXGRMGdj8yOqrlrjEp9uqi8D9SFgE/UTiWkBF4RRwVvZeo4lGGnll/CxJmtzuMXWa65TS0Z/a2QLdPyIH/3OomJH7sb3FgfQ== plaintext_old: {"google":{"secret":"0:3:LKm9642Rpl0gqlBha+m3FYWnQBBtLgjdLDvjfoPo923xmxd9ykbnvX0LucKI","active":true}} plaintext_new: {"google":{"secret":"1:3:m9mScDkTkeCdn2lXpwf5oMkL7lmgLOTYJXQyKbK\/m8QwDZVDNWI3CzH+uBaq","active":true}} ciphertext_new: 1:3:Tw/5ik2meBqzL8oodrudxmksrOekA/DbZE5+KgBAygFxp6Zx/A7vbMyHt4+N1MtQhlnqW/mAXL3l2kDpFHIQVvi2L+23o9mRpii2ldBwmuZgDlpQsm+Q4Hf8a+t2aUKndGOMeoH6xcZXFCConC+TUI+uregFXx6B5LU4ohCY52m/v7w= Dry run mode, no changes have been made ######################################################################################################################## Done
bin/magento gene:encryption-key-manager:get-cloud-keys
此命令用于获取重新加密的云环境变量。这个命令不会更新现有值,它只是在控制台返回新值。开发者需要手动在云控制台中更新这些值。
# No keys example $ bin/magento gene:encryption-key-manager:get-cloud-keys There is no old encrypted environment variables found # There is some encoded $ bin/magento gene:encryption-key-manager:get-cloud-keys --show-decrypted There is no old encrypted environment variables found The CLI command doesn\'t rewrite values. You have to update them manually in cloud console! Rows count: 4 ################################################################## Name: CONFIG__DEFAULT__SOME_KEY Dectypted value: dectypted_value Old Encrypted Value: 0:3:AAA1 New Encrypted Value: 1:3:BBB1 ################################################################## Name: CONFIG__DEFAULT__SOME_KEY_2 Dectypted value: dectypted_value_2 Old Encrypted Value: 0:3:AAA2 New Encrypted Value: 1:3:BBB2
注意事项
report.WARNING:无法反序列化值
这种情况不常见,由使用此模块和使用管理员控制器旋转加密密钥的人报告。刷新Redis缓存可以解决问题。
请确保您刷新Redis缓存
现在您可以继续进行如上所述的重新加密工作。
您已手动更换了加密密钥
您需要
- 恢复旧加密密钥
- 将旧密钥添加到新密钥之前,用
\n
分隔,并重复上述步骤
其他问题
搜索https://github.com/genecommerce/module-encryption-key-manager/issues以获取其他问题。