密钥管理实践

admin 2023年1月18日23:07:55评论41 views字数 15577阅读51分55秒阅读模式



1

密钥管理


密钥本地化会导致密钥分散在代码、配置文件中。缺乏统一管理,造成开发、维护成本巨大,另一方面,如果业务系统被黑客攻克,密钥就会随之泄露,黑客就能直接还原业务数据了。


一般情况下,我们习惯认为数据经过加密处理就是安全的,却忽视了由于设计不完善、实现不规范给系统带来的风险。应用中常见的反面例子有:

1.使用的密码算法强度不足。如使用MD5、SHA1算法哈希存储用户密码、手机号等。——可以通过彩虹表攻击在有限空间+时间内通过碰撞推导原文,目前业界已普遍采用强度更强的PBKDF2等算法替代。

2.密钥长度不足导致密钥空间有限,在现有计算条件下易于被暴力破解。如:64位(有效长度56位)密钥长度的DES密钥、1024位RSA密钥在现有硬件条件下,可在几天或几小时内实现破解。

3.算法使用不当,导致抗分析能力较弱。反面案例有:通过不安全的伪随机数产生密钥,导致碰撞概率极高;加密过程中初始向量IV为空,使差分攻击难度降低;HMAC摘要中未使用盐值导致重放等横向攻击。

4.未设置密钥更新机制、更新机制不合理或无法及时停用存在风险的密钥,导致密钥泄露风险逐渐提高。比如:通过构造收集足够多的明文/密文对之后,可以通过差分攻击极大提速密钥的破解。

5.密钥存储方案或存储环境存在泄露风险。如:通过配置文件、硬编码等方式存储密钥,攻击者可通过越权查看配置文件、反编译程序代码等方式获取密钥。

6.不合理的密钥分发机制导致密钥在分发、传输过程中泄露。如:线下传输密钥或直接将密钥明文以文件形式传递,导致密钥泄露的风险大大增加。

7.多应用间共享加密密钥,导致密钥、敏感数据的使用权限和范围无法收敛,同时应用密钥更新机制难以实施。

8.各业务方各自为政的密码学技术实现,导致难以对密钥使用、敏感数据流转进行统一审计和有效追溯。


从以上安全风险来看,密钥在生成、更新、存储、分发、使用过程中,存在着泄露、滥用、权限管控缺失、无法有效审计等风险,进而直接影响整个密码系统和应用方案的安全性。因此在密码技术实践过程中,密钥的安全保存、合理使用、最小授权、有效审计是系统的核心任务。




2

解决办法


密钥管理系统KMS(以AWS KMS为例)

密钥管理技术KMS通过将密钥分为三级进行管理:

•数据加密密钥(DEK):将用于数据加密的密钥,也称三级密钥(DEK);一般公司里面一个应用对应一个DEK;

•密钥加密密钥(KEK):保护三级的密钥,也称二级密钥(KEK 即对DEK进行加密);一般公司里面一个部门对应一个KEK,DEK在KEK管辖之内;

•根密钥(RootKey):保护二级密钥的密钥,也称一级密钥(RootKey,即是对KEK进行加密),根密钥构成了整个密钥管理系统的关键。


实现原理

1.用DEK(Data Encryption Key,数据加密密钥)给数据data加密,得到 encrypted data

密钥管理实践

2.将DEK 用KEK(Key Encryption Key,密钥加密密钥)加密,得到 encrypted data key

密钥管理实践

3.将encrypted data key 和 encrypted data 保存在一起

4.对master key重复加密,得到最上层的根密钥(Root Key)(明文)

5.根密钥(Root Key)属性:

– 它完完全全保存在内存里面,永远不会在物理介质里面保存下来。

– 它永远不会在公网传输。


分布式密钥管理系统 DKMS(以Nucypher为例)

DKMS是将KMS与PRE (Proxy re-encryption,代理重加密技术) 结合的产物。为了充分避免风险,确保节点的可靠,通常会建立多个节点,将重加密密钥保存在多个节点之上。解密时只需拿到符合规定数量的密钥片段就可组合为完整密钥对密文进行解密。

密钥管理实践


原理

1.Alice: Alice有些想要共享的数据,通过为数据分类(label)生成非对称密钥(公钥发送给Enrico用于数据加密,私钥+bob的公钥配合用于生成重加密密钥),将重加密密钥切分成n个片段,放于Nucypher网络节点。

2.Enrico:数据产生并且加密,Enrico产生一个随机的对称密钥,用对称密钥对数据进行加密,然后使用Alice提供的公钥对对称密钥进行加密,将加密的数据和加密的对称密钥,存放于分布式存储中。

3.Bob:从分布式存储中拿到Alice存储的数据(加密的数据和加密的密钥);从n个Nucypher网络节点中取得m个代理重加密密钥片段,组合生成代理重加密密钥(阈值门限加密算法);Bob就可以用自己的私钥对加密的密钥进行解密,解密后拿到数据加密用的对称密钥,即可解密得到数据。

4.Ursula: ursula节点是nucypher网络中的节点,通过多个ursula节点完成阈值代理重新加密操作。


操作流程

alice有一些数据,想要发送给一个或一些bob,这些数据可以假设是由enrico产生的。但是alice并不想直接使用bob的公钥对数据进行加密,因为下次alice想要把数据发送给另一个bob时,alice需要用另一个bob的公钥对数据再次进行加密,不仅浪费存储资源还浪费计算资源。所有引入了一个第三方代理重加密节点,即ursula。alice通过对bob进行授权,设置策略公钥(基于过期时间、标签分类等策略)。alice不用每次都用bob的公钥加密,但是bob可以通过自己私钥对数据进行解密。
本例中通过简单的一个ursula节点,对数据进行重加密,bob可以拿到alice的数据。


1. 系统环境

ubuntu20.04

python3.8.2

nucypher 3.0.0-beta.0


2. 节点运行

分别打开四个终端,进入nucypher工作的虚拟环境。


2.1 运行ursula节点

(my_nucy_env) aha@aha:~/Desktop/nucypher$ nucypher ursula run --dev --federated-only --console-logs

1

这一步至关重要,因为后续的alice,bob,enrico的运行都要使用ursula提供的服务。
     运行后可以看到如下界面:

密钥管理实践
密钥管理实践


2.2 运行alice节点

(my_nucy_env) aha@aha:~/Desktop/nucypher$ nucypher alice run --dev --federated-only --teacher localhost:10151 --console-logs
1

运行后显示如下。在这里可以看到Alice_Verifying_Key。

密钥管理实践


2.3 运行enrico节点

在运行enrico之前,我们需要拿到alice给enrico分配的策略密钥。
在这里我们使用python+jupyter进行演示如何拿到策略加密密钥。

alice = "http://localhost:8151"

Alice_Verifying_Key = "03bebf3d9631d53c4797be3246c49dcc213b2cb3843abf35449430030e7c7339b6"

derivation_response = requests.post(f"{alice}/derive_policy_encrypting_key/songs")

123

上一步的接口调用过程建议使用postman进行测试。

derivation_response.content

#可以看到其内容,policy_encrypting_key

b'{"result": {"policy_encrypting_key": "0224aa3b7e9f35d9fd0c7ab335068d9f43d20d14ec7473a0ca5848681acbb21454", "label": "songs"}, "version": "3.0.0-beta.0"}'

123

拿到policy_encrypting_key后在终端即可运行enrico节点。

nucypher enrico run --policy-encrypting-key 0224aa3b7e9f35d9fd0c7ab335068d9f43d20d14ec7473a0ca5848681acbb21454 --http-port 5152 --console-logs

1

运行成功后,可以看到下图输出。

密钥管理实践


2.4 运行bob节点

note: 如果alice想要将数据发送给其他的人,其使用角色仍是bob

(my_nucy_env)aha@aha:~/Desktop/nucypher$ nucypher bob run --dev --federated-only --teacher localhost:10151 --controller-port 11151 --console-logs

1

成功运行后,可以看到下图输出。这里的Bob_Verifying_Key和Bob_Encrypting_Key在下一步中都要用到。

密钥管理实践


3 alice向bob发送消息


3.1 python需要使用的包

from base64 import b64decode,b64encode

import json

import requests

123


3.2 构建alice对象

alice = "http://localhost:8151"

Alice_Verifying_Key = "03bebf3d9631d53c4797be3246c49dcc213b2cb3843abf35449430030e7c7339b6"

derivation_response = requests.post(f"{alice}/derive_policy_encrypting_key/songs")
123

这里通过post请求向alice发送数据,alice能够生成策略密钥,用于enrico加密数据。加入alice有很多数据,但是她不想把所有的数据都发送给bob,所有可以使用标签对数据进行分类,这里的songs即时标签label,可以是任意字符,表示alice仅想向bob分享此类数据。


3.3 构建enrico对象

enrico = "http://localhost:5152"

1


3.4 构段一段消息

构造一段明文消息,并封装成nucypher可以使用的数据类型(使用base64编码)。

message_to_encrypt = b"This is some plaintext"

encryption_request = { "message":b64encode(message_to_encrypt).decode() }
12

这里可以输出看到明文信息使用base64编码后encryption_request的具体数值{'message': 'VGhpcyBpcyBzb21lIHBsYWludGV4dA=='}。


3.5 enrico对数据进行加密

encryption_response = requests.post( f"{enrico}/encrypt_message",data=json.dumps(encryption_request) )
1

使用post请求将数据传送给enrico,可以拿到加密后的数据。

encryption_response.content

b'{"result": {"message_kit": "Ag7I5VUWoDpUwTcZ1aEmi36lIBFMHrv47iNQYbW7SJGcAjEIt9B6inZcprzdXURBLR71myktmLZYRiryZqe4fEWCTwYmxOsCSSGXt2FjTaJWR0mwx6pP1ZNIpQA7XOp4HXcDWvWthNC5bxbzEXTTl+4yDgFo8AonRyqqjZ+HHUONm+kAAACEvQDpeQff8QhoQkFnXZt0k/+S1/uZAkf3FFYj3Ur2Bl83B5zF3t0c2jVPMp787dvQoMR54wRVNnCw6YsNZUGS0BWzhOlm4oO9RHo5NV8lXIrqfsY7DCl4JR/yzj6NW8dc2HiImG1af5LTq325HxZjUsh7M7FDS0c27QYUYB11LFBB2oGm", "signature": "U6URG6VM9TOLH67lBcxOLQfOXzHNamqUS4QMoLvmdTh8gTFTzog0/FSsZNHtEYshYb0nUj2z12h5rZJ8cju11A=="}, "version": "3.0.0-beta.0"}'

1234

message_kit即原数据经过enrico加密的数据。取出message_kit后续使用。


3.6 构建bob对象

bob = "http://localhost:11151"

Bob_Verifying_Key = "0384a576c6370e37690d594681423528ac1c6c5a772ee8c6d20b47e550f41f6fd6"

Bob_Encrypting_Key =  "02684c17f80d25d3d625397faa12fa537a9be5a6406f42920dd19886827e319139"

123


3.7 构建需要检索的数据对象

retrieval = {}

retrieval["label"] = "songs"

retrieval["policy_encrypting_key"] = policy_encrypting_key

retrieval["alice_verifying_key"] = Alice_Verifying_Key

retrieval["message_kit"] = message_kit

12345


3.8 alice对bob进行授权

下面是授权所需要的基本信息,包括bob的签名密钥、加密密钥、数据标签、过期时间、以及基于阈值门限重加密的m和n(本例只运行一个ursula节点),所以都设置成1。

grant = {}

grant["bob_verifying_key"] = Bob_Verifying_Key

grant["bob_encrypting_key"] = Bob_Encrypting_Key

grant["m"] = 1

grant["n"] = 1

grant["label"] = "songs"

grant["expiration"] = 5

1234567

通过put请求,alice建立授权信息,授权后bob可以拿到加密的数据。

requests.put(f"{alice}/grant",data=json.dumps(grant))
1

注意:这里的put只能运行一次,多次运行会返回500错误,提示’Policy already exists in active_policies.’。


3.9 bob获取数据

retrieved =  requests.post(f"{bob}/retrieve",data=json.dumps(retrieval))

#retrieved.content

#b'{"result": {"cleartexts": ["VGhpcyBpcyBzb21lIHBsYWludGV4dA=="]}, "version": "3.0.0-beta.0"}'

123

这里的cleartexts里即包含了上文的message_kit。如果发送所条信息,也将包含在cleartexts中。


3.10 数据解码

retrieved_b64 = json.loads(retrieved.content)['result']['cleartexts']

#retrieved_b64

#['VGhpcyBpcyBzb21lIHBsYWludGV4dA==']

b64decode(retrieved_b64[0])

#b'This is some plaintext'

12345

即顺利拿到alice发送的数据。


总结

1.代理重加密
上例中用ursula充当代理重加密节点,具体细节全部由项目内部进行处理。使用过程中只需要将alice,bob等节点建立的ursula节点的服务之上即可。后续的操作过程中,并没有具体涉及到代理重加密的过程。只要通过alice进行授权,bob即可拿到数据。

2.阈值门限
在nucypher工作过程中,为了充分避免风险,确保ursula节点的可靠,通常会建立多个节点,把重加密密钥保存在多个节点之上,而授权后的bob只需要拿到规定数量的密钥片段即可组合成整个密钥,对秘文数据进行解密。




3

Android KeyStore密钥存储


Android KeyStore可以保护密钥材料免遭未经授权的使用。首先,Android KeyStore可以防止从应用进程和 Android 设备中整体提取密钥材料,从而避免了在 Android 设备之外以未经授权的方式使用密钥材料。其次,Android KeyStore可以让应用指定密钥的授权使用方式,并在应用进程之外强制实施这些限制,从而避免了在 Android 设备上以未经授权的方式使用密钥材料。

Android 密钥库密钥使用两项安全措施来避免密钥材料被提取:

• 密钥材料永不进入应用进程。通过 Android 密钥库密钥执行加密操作时,应用会在后台将待签署或验证的明文、密文和消息馈送到执行加密操作的系统进程。如果应用进程受到攻击,攻击者也许能使用应用密钥,但无法提取密钥材料(例如,在 Android 设备以外使用)。

• 可以将密钥材料绑定至 Android 设备的安全硬件,例如可信执行环境 (TEE) 和安全元件 (SE)。为密钥启用此功能时,其密钥材料永远不会暴露于安全硬件之外。如果 Android 操作系统受到攻击或者攻击者可以读取设备内部存储空间,攻击者也许能在 Android 设备上使用任意应用的 Android 密钥库,但无法从设备上提取这些数据。(只有设备的安全硬件支持密钥算法、分块模式、填充方案和密钥有权配合使用的摘要的特定组合时,才可启用此功能。)


keystore的作用

• 有利于程序升级:当新版程序和旧版程序的数字证书相同时,Android系统才会认为这两个程序是同一个程序的不同版本。如果新版程序和旧版程序的数字证书不相同,则Android系统认为他们是不同的程序,并产生冲突,会要求新程序更改包名。

• 有利于程序的模块化设计和开发:Android系统允许拥有同一个数字签名的程序运行在一个进程中,Android程序会将他们视为同一个程序。所以开发者可以将自己的程序分模块开发,而用户只需要在需要的时候下载适当的模块。

• 可以通过权限(permission)的方式在多个程序间共享数据和代码:Android提供了基于数字证书的权限赋予机制,应用程序可以和其他的程序共享功能或者将数据给那些与自己拥有相同数字证书的程序。如果某个权限(permission)的protectionLevel是signature,则这个权限就只能授予那些跟该权限所在的包拥有同一个数字证书的程序。


生成方式(keytool或者Android studio)

默认Keystore和自定义Keystore:

通常应用发布时不用默认的Keystore,因为它不包含开发者的有效信息,且密码是android,任何人都可通过keytool指令对其内容进行修改,无法验证APP的有效性。默认Keystore的存放位置为$HOME/.android/debug.keystore,若Android Studio打包签名apk的时候未找到默认的Keystore时会自动创建它。自定义Keystore可使用Keytool指令或Android Studio来生成。


Keytool指令参数

使用该指令可实现密钥库(Keystore)的创建和查看等操作。

-genkey

在用户主目录中创建密钥库(Keystore),后缀名为.keystore。
     -alias [alias]

产生别名,后面跟别名内容。若未指定,则别名默认为mykey.

-keystore

指定.keystore文件的名称,如:

keytool -genkey -keystore dmkf.keystore

用户主目录中会产生名称为dmkf.keystore的Keystore文件。若未使用该参数,则文件名默认为.keystore。

-keyalg [DSA/RSA]

指定密钥的算法,未指定时默认为DSA算法。

-validity

指定创建的证书有效期,单位为天。未指定时默认为1天。

-dname

证书持有者(APP开发者)信息。

CN:名字或姓氏

OU:组织单位名称

O:组织名称

L:城市或区域名称

ST:州或省份名称

C:单位的两字国家代码

-list

显示证书信息。

-v

显示证书详细信息。

-export

结合-alias导出指定的证书信息。如:

keytool -export -alias dmkf -keystore dmkf.keystore -file D:/mykeystore/myexport.crt

-import
将已签名的证书导入到密钥库,如:

keytool -import -alias dmkf -keystore mystore.keystore -file D:/mykeystore/myanother.crt

-keysize

指定密钥长度。

-storepass

操作密钥库所需的密码。

-storepasswd

修改操作密钥库所需的密码。

-keypass

指定别名条目的密码(私钥的密码)。

-keypasswd

修改指定别名条目的密码。

-file

结合-export,指定导出的证书位置及证书名称。

-delete

删除密钥库中某一条目。如:

keytool -delete -alias dmkf -keystore dmkf.keystore

-printcert

查询导出的证书信息,如:

keytool -printcert -file D:/mykeystore/dmkf.crt


常用Keytool指令操作

 创建Keystore文件
生成一个别名为dmkf,名为dmkf.keystore的文件。

keytool -genkey -alias dmkf -keystore dmkf.keystore -keyalg RSA

• 查看Keystore文件
查看名为dmkf.keystore的Keystore文件信息。

keytool -list -v -keystore dmkf.keystore
Enter keystore password: ****(输入Keystore操作密码)

• 输出Keystore证书
从密钥库dmkf.keystore中导出别名为dmkf的证书到dmkf.crt文件中(导出的证书中包括主体信息和公钥)。

keytool -export -alias dmkf -keystore dmkf.keystore -file dmkf.crt
Enter keystore password: ****(输入Keystore操作密码)

• 查看导出的证书信息
查看导出并保存在dmkf.crt文件中的证书信息。

keytool -printcert -file dmkf.crt

• 导入证书
从名为dmkf.crt文件中取出别名为dmkf的证书信息导入到名为truststore.keystore密钥库中。

keytool -import -alias dmfk -keystore truststore.keystore -file dmkf.crt


Android Studio生成Keystore

打开Android Studio,在菜单栏中找到Build,单击弹出下拉框,选择Generate Signed APK...。

密钥管理实践

选择app,单击Next按钮。

密钥管理实践

单击Create new...按钮。

密钥管理实践

在弹出的New Key Store窗口中选择Keystore存放路径,设置Keystore密码、别名、别名密码、有效期以及个人信息,单击OK按钮完成Keystore的创建。

密钥管理实践

此时Android Studio自动填充新建的Keystore相关信息,至此Android Studio已完成Keystore的创建。若想用这个Keystore继续打包APK,单击Next按钮。

密钥管理实践

设置密码数据库的密码,单击OK按钮,进入下一步。

密钥管理实践

选择好APK导出的位置和编译方式(发布/调试),单击Finish按钮完成APK的打包。

密钥管理实践

在项目根目录的app文件夹里可以找到命名为app-release.apk的apk文件。

密钥管理实践




4

KeyChain(ios密钥管理)


Keychain Services 是 macOS 和 iOS 提供的一种安全的存储敏感信息的工具,比如,网络密码:用户访问服务器或者网站,通用密码:用来保存应用程序或者数据库密码。与此同时,用于认证的证书,密钥,和身份信息,也可以存储在Keychain中。Keychain Services 的安全机制保证了存储这些敏感信息不会被窃取。简单说来,Keychain 就是一个安全容器。

在iOS中keychian 依赖用于签名的provisioning profile描述文件,确保发布不同版本的时候使用同一个pp文件。且iOS中仅存在一个全局性的Keychain(macOS中可以设置多个keychain)

在Keychain机制中,通过kSecClass来指明保存的数据信息类型,目前共支持五种信息类型:

kSecClassGenericPassword used to store a generic password(通用密码)

kSecClassInternetPassword used to store an internet password(互联网密码)

kSecClassCertificate used to store a certificate(证书)

kSecClassKey used to store a kryptographic key(密钥)

kSecClassIdentity used to store an identity (certificate + private key)(身份)


Keychain item结构

Keychain中所存储的条目,被称之为Keychain item(keychain item称为SecItem,但它是存储在CFDictionary中的),Keychain可以包含任意数量的keychain item。

keychain item其实是一个字典似得数据结构,即一个key对应一个value,我们操作Keychain中的数据的时候,也是以字典的结构来进行操作的。

Keychain item中存储的数据可以划分为三个区域:

•一个表明存储的数据类型,其key前缀为kSecClass

•一组描述数据信息的属性,其key前缀为kSecAttr

•存储敏感数据的内容,其key前缀为kSecValue


•kSecAttr——唯一标识Keychain item的关键

每个Keychain item都是用了一组属性来唯一的描述,当我们需要对Keychian item进行操作时,也是通过这组属性来定位的。同时,对于重要的要加密的信息,IOS也是通过几个关键属性来对应生成私钥进行加解密的。对于每个class的关键属性(git上一个人爬开源代码和手册总结的属性组合)


•For a keychain item of class kSecClassGenericPassword, the primary key is the combination of kSecAttrAccount and kSecAttrService.

•For a keychain item of class kSecClassInternetPassword, the primary key is the combination of kSecAttrAccount, kSecAttrSecurityDomain, kSecAttrServer, kSecAttrProtocol, kSecAttrAuthenticationType, kSecAttrPort and kSecAttrPath.

•For a keychain item of class kSecClassCertificate, the primary key is the combination of kSecAttrCertificateType, kSecAttrIssuer and kSecAttrSerialNumber.

•For a keychain item of class kSecClassKey, the primary key is the combination of kSecAttrApplicationLabel, kSecAttrApplicationTag, kSecAttrKeyType, kSecAttrKeySizeInBits, kSecAttrEffectiveKeySize, and the creator, start date and end date which are not exposed by SecItem yet.

•For a keychain item of class kSecClassIdentity I haven't found info on the primary key fields in the open source files, but as an identity is the combination of a private key and a certificate, I assume the primary key is the combination of the primary key fields for kSecClassKey and kSecClassCertificate.

As each keychain item belongs to a keychain access group, it feels like the keychain access group (field kSecAttrAccessGroup) is an added field to all these primary keys.


Keychain的特点

• 数据并不存放在App的Sanbox中,即使删除了App,资料依然保存在Keychain中。如果重新安装了App,还可以从Keychain获取数据。

• Keychain的数据可以通过group方式,让程序可以在App间共享。不过得要相同TeamID。

• keychain的数据是经过加密的。


Keychain的使用

对于每一个应用来说,KeyChain都有两个访问区,私有区和公共区。私有区是一个sandbox,本程序存储的任何数据都对其他程序不可见,其他应用程序无法访问该区数据。Keychain中保存的信息是用app unique签名了的,默认只有自己能够访问。如果要想将存储的内容放在公共区,实现多个应用程序间可以共同访问一些数据,则可以先声明公共区的名称,官方文档管这个名称叫“keychain access group”


keychain的access group的概念

a) app保持的信息是用一个app unique 签名了的,默认只有自己能够访问。

b)不同app之间可以通过access_group共享

app1的group是 app1.accessgroup.item1,

app2在entitlements中加入这个item就可以访问了。

c)在不同app之间共享,只能在同一个公司内部的app共享。 

因为keychain access group 所在的文件entitlements.plist,需要添加到code_sign_entitlements.

这个文件的路径要配置在 Project->build setting->Code Signing Entitlements里,否则公共区无效,配置好后,须用你正式的证书签名编译才可通过,否则xcode会弹框告诉你code signing有问题。所以,苹果限制了你只能同公司的产品共享KeyChain数据,别的公司访问不了你公司产品的KeyChain。


apple提供了四个函数用来进行密码的查找、添加、更新、删除等操作。

•查找

查找前,先配置dictionary。在下面的代码中配置了这个dictionary四个部分的后两个部分,即Search key-value和返回类型的key-value.

 - (BOOL)fetch

{

    CFTypeRef result = NULL;

    NSMutableDictionary *query = [self query];

    //YES本来是一个值,@YES就变成了一个对象,可用[NSNumber numberWithBool];代替

    [query setObject:@YES forKey:(__bridge id)kSecReturnData];

    [query setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];

    OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result);

    if (status != errSecSuccess) {

        return NO;

    }

    self.passwordData = (__bridge_transfer NSData *)result;

    return YES;

}


•添加、更新

添加、更新前首先查找。此处的dictionary只配置了四部分中的前两部分,原因是,apple已经有默认的配置。

 - (BOOL)save

{

    NSMutableDictionary *query = nil;

    NSMutableDictionary *searchQuery = [self query];

    //添加前首先查找是否存在要添加的密码

    OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)searchQuery, nil);

    if (status == errSecSuccess) {//item 已经存在,更新它

        query = [[NSMutableDictionary alloc] init];

        [query setObject:self.passwordData forKey:(__bridge id)kSecValueData];

        status = SecItemUpdate((__bridge CFDictionaryRef)searchQuery, (__bridge         CFDictionaryRef)query);

    } else if (status == errSecItemNotFound) {//item未找到,创建它

        query = [self query];

        [query setObject:self.passwordData forKey:(__bridge id)kSecValueData];

        status = SecItemAdd((__bridge CFDictionaryRef)query, NULL);

    }

    return (status == errSecSuccess);

}


•删除

删除相对简单,找到了,就删除

 - (BOOL)deleteItem

{

NSMutableDictionary *query = [self query];

OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query);

return (status == errSecSuccess);

}




5

一些开源的密钥管理系统(可供参考)


• KeyBox - web-based SSH access and key management(https://web.archive.org/web/20170709204709/https://github.com/skavanagh/KeyBox)

• EPKS - Echo Public Key Share, system to share encryption keys online in a p2p community.()

• Kmc-Subset137(https://web.archive.org/web/20170630055938/http://www.kmc-subset137.eu/)

• StrongKey - open source, last updated on Sourceforge in 2013.[11]

• Vault - secret server from HashiCorp(英语:HashiCorp).[12]




6

密钥拆分技术(密钥隐藏技术的一种)


密钥拆分技术,通过改变算法流程,将用户的密钥拆分成多个无关的子密钥,隐藏到系统的不同地方。需要密码执行的时候通过调用看似无关的密码函数计算出需要的密码计算结果。

Secret sharing是一类能够实现将一个secret分成n个share,并且只有当至少有k个share时才能恢复该secret。Secret sharing在安全多方计算(SMC)中有着重要应用。

Shamir's secre sharing scheme(ssss)是secret sharing的一个具体实现方案,它利用多项式的特性及拉格朗日插值实现share的生成及secret的恢复,并能提供information theoretic security。


1. polynomial

对于k-1次多项式:

密钥管理实践
密钥管理实践

1.1 拉格朗日内插法

实际上,为了计算f(x)在其它点的值,无需先求所有系数,可以直接利用拉格朗日插值求任意f(x)。

密钥管理实践


2 Shamir's Secret Sharing Scheme

密钥管理实践


3 进阶

SSSS可以进行横向或者纵向更新,横向更新指增加新的share,纵向更新指刷新原来的share但是保持secret不变。横向更新较简单,利用拉格朗日插值计算曲线在新的x处的函数值即可。

纵向更新则先选一条新的常数项为0的随机曲线。

密钥管理实践


               END               

密钥管理实践

直达链接

往期精彩推荐

RSA-CRT 故障注入攻击

PE文件签名信息检测

联想集团第五届网络安全周活动圆满结束!

●隐私保护知多少

横向联邦学习技术原理浅析

●Windows DLL劫持漏洞分析

●利用Firmadyne进行固件模拟

●构造溯源蜜罐——伪造MySQL服务端

●Cisco RV110W 堆栈缓冲区溢出漏洞分析

CSL

密钥管理实践

 联想GIC全球安全实验室(中国)[email protected]

原文始发于微信公众号(联想全球安全实验室):密钥管理实践

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年1月18日23:07:55
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   密钥管理实践https://cn-sec.com/archives/1520833.html

发表评论

匿名网友 填写信息