我已经为这个问题苦苦思索了大约 20 个小时,我可能遗漏了一些简单的东西。但是,我已经到了我认为需要帮助的地步。我已经阅读了数十种关于如何解决问题不同部分的解释,但我无法弄清楚如何将它们组合在一起。
我有一个 DER 编码的分离 PKCS#7 数字签名。签名符合 RFC 3852(加密消息语法)。对于我的项目,我需要逐步完成验证签名所需的每个步骤,并能够判断验证失败的步骤。我在 Java 中使用 BouncyCaSTLe。
据我了解,验证数字签名需要六个基本步骤
编辑:一些评论要求将 OSCP 检查添加到列表中。
在 BouncyCaSTLe 测试代码中,我能够找到以下示例。它似乎完成了 2/6,但是并不清楚它是否完成了任何任务。如果有人能为我指出其余任务的正确方向,将不胜感激。
CMSSignedData s = ...
byte[] contentDigest = ...
Store certStore = s.getCertificates();
Store crlStore = s.getCRLs();
SignerInformationStore signers = s.getSignerInfos();
Collection c = signers.getSigners();
Iterator it = c.iterator();
while (it.hasNext())
{
SignerInformation signer = (SignerInformation)it.next();
Collection certCollection = certStore.getMatches(signer.getSID());
Iterator certIt = certCollection.iterator();
X509CertificateHolder cert = (X509CertificateHolder)certIt.next();
assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert)));
if (contentDigest != null)
{
assertTrue(MessageDigest.isEqual(contentDigest, signer.getContentDigest()));
}
}
Collection certColl = certStore.getMatches(null);
Collection crlColl = crlStore.getMatches(null);
assertEquals(certColl.size(), s.getCertificates().getMatches(null).size());
assertEquals(crlColl.size(), s.getCRLs().getMatches(null).size());
最佳答案
CMS 签名数据验证中最复杂的是 X.509 验证部分。对于签名数据中的每个签名者,步骤如下:
<强>1。找到签署者证书
SignerInformation signerInfo = (SignerInformation)it.next();
Collection certCollection = certStore.getMatches(signerInfo.getSID());
Iterator certIt = certCollection.iterator();
X509CertificateHolder signerCertificateHolder = (X509CertificateHolder)certIt.next();
我假设这里只有一个匹配的证书。
<强>2。查找从签署者证书到受信任的根证书的证书链
在这里,您要检查 Store 中的证书以找到证书链。使用主题 DN/发行者 DN 和主题 key 标识符/授权 key 标识符匹配来构建该链。
<强>3。验证链
此步骤递归验证链中的每个证书。对于每个证书,从直接在根证书下的证书开始您需要检查:
希望您可以在第 2 步和第 3 步中使用内置的 PKIX 证书路径构建器和验证机制:
KeyStore trustAnchors = getTrustAnchors();
X509CertSelector target = new X509CertSelector();
target.setCertificate(signerCertificate);
PKIXBuilderParameters params = new PKIXBuilderParameters(anchors, target);
CertStoreParameters additionalCerts = new CollectionCertStoreParameters(allOtherCerts)
params.addCertStore(CertStore.getInstance("Collection", additionalCerts));
CertStoreParameters revocationObjects = new CollectionCertStoreParameters(allCRLs);
params.addCertStore(CertStore.getInstance("Collection", revocationObjects));
CertPathBuilder builder = CertPathBuilder.getInstance("PKIX");
PKIXCertPathBuilderResult r = (PKIXCertPathBuilderResult) builder.build(params);
/* if the build method returns without exception, the certificate chain is valid */
为了可读性,我省略了对象在 java(x).crypto 和 BouncycaSTLe 类型之间的转换。
<强>4。使用公钥验证 SignerInfo 签名
JcaSimpleSignerInfoVerifierBuilder builder = new JcaSimpleSignerInfoVerifierBuilder();
SignerInformationVerifier verifier = builder.build(signerCertificateHolder);
assertTrue(signerInfo.verify(verifier));
<强>5。验证文档摘要是否与签名摘要匹配
byte[] contentDigest = computeDigest(originalDoc, signerInfo.getDigestAlgOID());
assertArrayEquals(contentDigest, signer.getContentDigest());
强>强>强>强>强>关于java - 结合验证 PKCS#7 签名所需的所有任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20853157/
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
我在开发的Rails3网站的一些搜索功能上遇到了一个小问题。我有一个简单的Post模型,如下所示:classPost我正在使用acts_as_taggable_on来更轻松地向我的帖子添加标签。当我有一个标记为“rails”的帖子并执行以下操作时,一切正常:@posts=Post.tagged_with("rails")问题是,我还想搜索帖子的标题。当我有一篇标题为“Helloworld”并标记为“rails”的帖子时,我希望能够通过搜索“hello”或“rails”来找到这篇帖子。因此,我希望标题列的LIKE语句与acts_as_taggable_on提供的tagged_with方法
我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123
我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
如何使用RSpec::Core::RakeTask初始化RSpecRake任务?require'rspec/core/rake_task'RSpec::Core::RakeTask.newdo|t|#whatdoIputinhere?endInitialize函数记录在http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method没有很好的记录;它只是说:-(RakeTask)initialize(*args,&task_block)AnewinstanceofRake
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我有一些非常大的模型,我必须将它们迁移到最新版本的Rails。这些模型有相当多的验证(User有大约50个验证)。是否可以将所有这些验证移动到另一个文件中?说app/models/validations/user_validations.rb。如果可以,有人可以提供示例吗? 最佳答案 您可以为此使用关注点:#app/models/validations/user_validations.rbrequire'active_support/concern'moduleUserValidationsextendActiveSupport: