OpenSAML 使用引导 IV: 安全特性

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 本文将专注讨论OpenSAML中安全特性,包括如何管理密钥,如何对断言信息签名,如何对断言信息加密等。相关阅读SAML2.0入门指南,OpenSAML 使用引导 I : 简介OpenSAML 使用引导 II : Service Provi...

本文将专注讨论OpenSAML中安全特性,包括如何管理密钥,如何对断言信息签名,如何对断言信息加密等。
相关阅读

  1. SAML2.0入门指南,
  2. OpenSAML 使用引导 I : 简介
  3. OpenSAML 使用引导 II : Service Provider 的实现之AuthnRequest
  4. OpenSAML 使用引导 III: Service Provider 的实现之Artifact与断言

源码地址:https://github.com/sunrongxin7666/OpenSAML-ref-project-demo-v3.git

1. OpenSAML中的证书对象

证书对象(Credential)中包含密钥信息,密钥可以是对称的,也可以是非对称的,可能是一个也可能是多个,其重要的作用就作为密钥的容器存在。证书对象和我们通常说的数字证书不是一个概念。

1.1 生成证书对象

证书对象Credential可以通过KeySupport工具自动生成。KeySupport可以生成对称密钥和非对称密钥对,下面的例子是生成RSA密钥对,并生成证书对象:

KeyPair keyPair = KeySupport.generateKeyPair("RSA", 1024, null);
return CredentialSupport.getSimpleCredential(keyPair.getPublic(), keyPair.getPrivate());

1.2 读取已用的密钥到证书对象

如何读取已经存在的密钥到证书对象中?OpenSAML推荐的方法是去使用各种CredentialResolvers类对象把已经存在的密钥放入新创建的证书对象中。

比如密钥被存放在JavaKeyStore中,相应地久应该使用KeyStoreCredentialResolver,其构造函数需要key store和密钥别名与口令的Map。

Map<String, String> passwordMap 
    = new HashMap<String, String>();
passwordMap.put(KEY_ENTRY_ID, KEY_STORE_ENTRY_PASSWORD);
KeyStoreCredentialResolver resolver = 
    new KeyStoreCredentialResolver(keystore, passwordMap);

通过带有key别名的criterion来查询credential resolver中的credentials。

Criterion criterion = new EntityIDCriterion(KEY_ENTRY_ID);
CriteriaSet criteriaSet = new CriteriaSet(criterion);
resolver.resolveSingle(criteriaSet);

除此之外还有如下常用CredentialResolver:

  • MetadataCredentialResolver:在SAML Metadata中获得密钥创建证书对象;
  • FilesystemCredentialResolver:在文件系统中获得密钥创建证书对象。

2. OpenSAML中的密码签名

签名是密码学一个证明数据完整性的手段。OpenSAML中提供了工具来对短信信息经行签名以及验证签名。由于断言的表现形式是一种XML,所以其签名也是基于XML签名方法。

2.0 XML的签名方法

这里先简要介绍下XML文件的签名方法,具体关于细节可以参见以下文章:

含有签名的断言

断言的签名

其大致流程为:

  1. 确定需要确认XML文档中哪些内容签名,通过URI将这些数据项目表示为引用资源 ,以Reference元素表示。对于断言消息来说,整个断言都是需要加密的,所以其URI为断言的ID;
  2. 对待签名的数据进行转化处理,包括制定的编码规则、规范化算法以及应用于已签名数据的XSLT转换,transform元素用于指定要应用的算法;
  3. 转化后,对每个Reference元素中引用的URI资源应用消息摘要算法(由于是对整个断言签名,所以只会出现一个Reference元素);DigestMethod元素指定元素应用的消息摘要算法,消息摘要值将存储在DigestValue元素中;
  4. 构造包含Reference元素的SignedInfo元素,
  5. 使用CananonicalizationMethod元素指定的规范化算法对SignedInfo元素进行规范化,如果不进行规范化,验证XML签名将可能因为XML结构或者表示方便不同而失败; XML规范标准见此处;
  6. 计算SignedInfo元素的摘要,并使用SignatureMethod元素中声明的签名算法,对其进行签名,得到的签名值放到SignatureValue元素中;
  7. 添加KeyInfo元素(可选),表面签名所使用的密钥信息,如果双方已经提前协商好密钥信息,就可以省却该项;
  8. 构造Signature元素,其中包括SignedInfoSignedValueKeyInfo等元素;

核实和验证XML的签名:

  1. 核实和验证摘要值: 重新计算Refernce元素引用的数据对象的摘要值,计算过程包括应用Transforms元素制定进行转换,并使用DigestMethod元素指定的算法计算转化结果摘要,最后将计算得到的摘要值与DigestValue元素中的值进行比较
  2. 核实和验证签名: 使用KeyInfo元素包含的或者从外部资源获得的密钥信息重新计算SignedInfo元素中的签名;将计算得到的签名值与SignatureVlue元素的值进行比较。

2.1 对数据签名

在OpenSAML中,每一个实现SignableXMLObject接口的对象都可以被签名。签名的产生一共分为4步:

  1. 创建签名类对象并赋予签名属性:
Signature signature = OpenSAMLUtils
    .buildSAMLObject(Signature.class);
//设定证书对象,其中包含密钥
signature.setSigningCredential(credential);
//设定签名算法
signature
    .setSignatureAlgorithm(SignatureConstants
.ALGO_ID_SIGNATURE_RSA_SHA1);
//设定XML规范化算法
signature
    .setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
  1. SignableXMLObject对象和签名类对象绑定起来:
signableXMLObject.setSignature(signature);
  1. 将SignableXMLObject对象序列化为XML对象
XMLObjectProviderRegistrySupport
    .getMarshallerFactory()
    .getMarshaller(object)
    .marshall(object);
  1. 使用Signer工具类生成签名
Signer.signObject(signature);

在一些情况下,OpenSAML会自动完成了签名的的过程,比如在传输SAML消息时,详见关于HTTPRedirectDeflateEncoder的内容。

2.2 验证签名

在验证签名之前最好是判断该消息是否被签名:

if (!assertion.isSigned()) {
    throw new RuntimeException("The SAML Assertion was not signed");
}

验证签名的第一步是判断该签名是否符合SAML签名的标准声明,也就是是否应用了XML的规范化算法:

SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator();
profileValidator.validate(assertion.getSignature());

然后再进行真正密码学意义上的验证签名:

SignatureValidator sigValidator = new SignatureValidator(credential);
sigValidator.validate(assertion.getSignature());

SignatureValidator对象中被设置了credential对象,其中包含密钥信息。

3. OpenSAML中的加密

在OpenSAML中断言信息需要加密处理,要求使用一个对称密钥来来加密数据,同时用另外一个而非对称密钥用来加密这个对称密钥。断言的密文和密钥的密文都会在ArtifactResponse体现出来。

加密后断言

3.1 加密断言流程

  1. 为加密过程设置参数,即定义使用什么算法来加密断言数据:
DataEncryptionParameters encryptionParameters = 
    new DataEncryptionParameters();
encryptionParameters
    .setAlgorithm(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128);
  1. 设定使用何种算法对上一步用来加密数据的对称密钥进行非对称加密:
KeyEncryptionParameters keyEncryptionParameters
    = new KeyEncryptionParameters();
keyEncryptionParameters
    .setEncryptionCredential(SPCredentials.getCredential());
keyEncryptionParameters.setAlgorithm(
    EncryptionConstants
    .ALGO_ID_KEYTRANSPORT_RSAOAEP);
  1. 利用以上两个参数来生成加密对象:
Encrypter encrypter = new Encrypter(encryptionParameters, keyEncryptionParameters);
  1. 设置被加密的对称密钥的位置,这里设置为ArtifactResponse中KeyInfo元素的内置元素,还可以设置为Peer模式就是和KeyInfo元素并列:
encrypter.setKeyPlacement(Encrypter.KeyPlacement.INLINE);
  1. 使用Encrypter加密数据
EncryptedAssertion encryptedAssertion = encrypter.encrypt(assertion);

Encrypter不光可以加密Assertion,Attribute和NameID等XMLObject都可以被加密。

3.2 解密流程

keyInfoCredentialResolver用于获得非对称密码要,该密钥用于解密对称密钥;再使用对称密钥获得数据。

StaticKeyInfoCredentialResolver keyInfoCredentialResolver = new StaticKeyInfoCredentialResolver(
    SPCredentials.getCredential());
    
Decrypter decrypter = new Decrypter(
    null,
    keyInfoCredentialResolver, 
    new InlineEncryptedKeyResolver());
    
decrypter.decrypt(encryptedAssertion);

更多关于SAML协议的是实现的内容,请参见本人编写的一系列教程文章,其介绍如何使用OpenSAML,欢迎阅读指正:

  1. OpenSAML 使用引导 I : 简介
  2. OpenSAML 使用引导 II : Service Provider 的实现之AuthnRequest
  3. OpenSAML 使用引导 III: Service Provider 的实现之Artifact与断言
  4. OpenSAMl 使用引导IV: 安全特性
相关文章
|
6月前
|
存储 算法 数据库
【C++ 软件设计思路】学习C++中如何生成唯一标识符:从UUID到自定义规则
【C++ 软件设计思路】学习C++中如何生成唯一标识符:从UUID到自定义规则
334 0
|
4月前
|
机器学习/深度学习 存储 人工智能
hypernetwork在SD中是怎么工作的
Stable Diffusion中的hypernetwork是一种微调技术,由 Novel AI 开发,用于修改模型的风格,特别是噪声预测器中的交叉注意力模块。Hypernetwork 是一个小型网络,它通过两个子网络变换 key 和 query 向量,动态调整注意力机制。这不同于传统的超网络,它生成另一网络的权重。与LoRA相比,两者都修改注意力模块,但方法不同。Hypernetwork 训练快速,资源需求低,适用于普通计算机。使用时,模型文件应放在 `stablediffusion-webui/models/hypernetworks` 目录下,并通过WebUI或命令行指定。
|
存储 传感器 索引
ov2640子设备视频操作详细分析
ov2640子设备视频操作详细分析
335 0
ov2640子设备视频操作详细分析
|
6月前
|
存储 算法 安全
在线SM4加密/解密工具
在线SM4加密/解密工具支持快速、便捷地对数据进行SM4算法加密与解密。
475 0
|
安全 数据安全/隐私保护
下图中,仿照CBC模式修改的工作模式安全性如何?
下图中,仿照CBC模式修改的工作模式安全性如何?
|
存储 算法 芯片
ov2640子设备核心操作详细分析
ov2640子设备核心操作详细分析
266 0
|
算法
Qt实现一个重复文件检测小工具(原理:通过md5校验)
Qt实现一个重复文件检测小工具(原理:通过md5校验)
292 0
|
数据安全/隐私保护 Android开发
android11.0(R) data分区节点加密控制分析
android11.0(R) data分区节点加密控制分析
799 0
|
存储 Linux
“安装centOS7.0出现‘你没有创建加载器第一阶段设备,你没有创建可引导分区’,并提示可用空间不足”的解决方案
“安装centOS7.0出现‘你没有创建加载器第一阶段设备,你没有创建可引导分区’,并提示可用空间不足”的解决方案
|
存储 安全
这个工具可以清除软件代码项目中的硬编码密钥
本文讲的是这个工具可以清除软件代码项目中的硬编码密钥,Truffle Hog可以在源代码存储库内找到20个字符或以上的访问令牌和密钥
1658 0