我正在尝试验证 PDF 的数字签名。
我知道,当 PDF 被签名时,会定义一个字节范围,嵌入证书,并且根据我的阅读,签名的消息摘要和时间戳也存储在 PDF 中。
我已经可以提取证书并验证它们。现在我正在尝试验证 pdf 的完整性,但我的问题是我不知道签名的消息摘要位于何处。
在这个来自 Adobe 的签名 pdf 示例(http://blogs.adobe.com/security/SampleSignedPDFDocument.pdf)中,我可以清楚地识别摘要,因为它位于嵌入证书的下方:/DigestMethod/MD5/DigestValue/(第 1520 行) )。
但那个 PDF 样本似乎是 2009 年的,我怀疑消息摘要现在以不同的方式存储,因为我用 Adobe Reader 和 iText 签署了 PDF,但我找不到像以前那样的任何消息摘要字段一。有人可以判断摘要现在是否以不同的方式存储吗?他们位于哪里?
不管怎样,现在我正在使用 Adobe 的示例文档,并尝试验证其完整性。我正在根据指定的字节范围对文档的字节进行签名,并使用 MD5 算法对它们进行摘要,但是我得到的摘要值与消息摘要字段中的摘要值不匹配...我做错了什么吗?摘要是否也使用签名者的私钥进行签名?
我很感激任何帮助。
我正在尝试使用 Python 加密库验证签名,如此处所述https://cryptography.io/en/latest/hazmat/primitives/ametry/rsa/

这是在客户端-服务器 TCP 聊天应用程序的上下文中,客户端计算了签名,并将其发送到客户端以验证它确实是正确的服务器。签名被传递给函数进行验证。
def VerifySignature(signature):
with open("server_publickey.pem", "rb") as key_file:
public_key = serialization.load_pem_public_key(
key_file.read(),
#password=None,
backend=default_backend()
)
verifier = public_key.verifier(
signature,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
message = b"the message that the server verified"
verifier.update(message)
if verifier.verify():
return 1
else:
return 0
Run Code Online (Sandbox Code Playgroud)
我注意到返回了 0。根据密码学规范,看起来如果 verifier.verify() 失败,它会返回异常,所以我不知道如何测试它。
import android.os.Bundle;
import android.util.Base64;
import android.widget.Toast;
import org.bouncycastle.jce.provider.BouncyCastleProvider; // implementation 'org.bouncycastle:bcprov-jdk16:1.46'
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
static final String PUBLIC_KEY = "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEMEV3EPREEDc0t4MPeuYgreLMHMVfD7iYJ2Cnkd0ucwf3GYVySvYTttMVMNMEKF554NYmdrOlqwo2s8J2tKt/oQ==";
static final String DATA = "Hello";
static final String SIGNATURE = "MEUCIQCsuI4OcBAyA163kiWji1lb7xAtC8S0znf62EpdA+U4zQIgBcLbXtcuxXHcwQ9/DmiVfoiigKnefeYgpVXZzjIuYn8=";
static boolean verifyData() throws Exception {
PublicKey pk = getPublicKey();
byte[] signatureBytes = Base64.decode(SIGNATURE, Base64.NO_WRAP);
Signature signature = Signature.getInstance("SHA256withECDSA", "BC");
signature.initVerify(pk);
signature.update(DATA.getBytes("UTF-8"));
return signature.verify(signatureBytes);
}
static PublicKey getPublicKey() throws Exception {
Security.addProvider(new BouncyCastleProvider()); …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 DSS 签署 PDF 文档,但我的问题是我无法在服务器 A 中计算文档的哈希值,然后在服务器 B 中对其进行签名。
知道服务器 A 包含 PDF 文档,并且在服务器 B 中我们检索用于签名的证书
我的问题是如何在不需要证书的情况下计算服务器 A 中文档的哈希值。然后发送到服务器B请求签名?
更新 :
****** 哈希的准备和计算 ********
IPdfObjFactory pdfObjFactory = new ServiceLoaderPdfObjFactory();
PDFSignatureService pdfSignatureService = pdfObjFactory.newPAdESSignatureService();
PAdESSignatureParameters parameters = new PAdESSignatureParameters();
parameters.setDigestAlgorithm(DigestAlgorithm.SHA512);
parameters.setReason("Preuve de signature");
parameters.setLocation("MAROC");
parameters.setGenerateTBSWithoutCertificate(true);
SignatureImageParameters imageParameters = new SignatureImageParameters();
imageParameters.setPage(1);
FileDocument imageFile = new FileDocument("logo.png");
RemoteDocument fileImage = RemoteDocumentConverter.toRemoteDocument(imageFile);
DSSDocument image = RemoteDocumentConverter.toDSSDocument(fileImage);
// set an image
imageParameters.setImage(image);
imageParameters.setxAxis(350);
imageParameters.setyAxis(400);
imageParameters.setWidth(200);
imageParameters.setHeight(100);
parameters.setImageParameters(imageParameters);
SignatureImageTextParameters textParameters = new SignatureImageTextParameters();
DSSFont font …Run Code Online (Sandbox Code Playgroud) 我试图在Windows上生成数字签名(来自XP SP3,但目前正在使用Windows 7进行测试),其中CryptoAPI将与以下openssl命令兼容:
openssl dgst -sha256 -sign <parameters> (for signing)
openssl dgst -sha256 -verify <parameters> (for validation)
Run Code Online (Sandbox Code Playgroud)
我想使用Windows"MY"密钥库中的私钥进行签名.
我设法使用SHA1摘要算法使用以下CryptoAPI函数签署文件(为简洁省略参数):
CertOpenStore
CertFindCertificateInStore
CryptAcquireCertificatePrivateKey
CryptCreateHash (with CALG_SHA1)
CryptHashData
CryptSignHash
Run Code Online (Sandbox Code Playgroud)
生成的签名与"openssl dgst -sha1 -verify"兼容(一旦字节顺序颠倒).
我的问题是:当我尝试将CALG_SHA_256与CryptCreateHash一起使用时,它会因错误80090008(NTE_BAD_ALGID)而失败.通过谷歌搜索左右,我发现,我需要使用特定的提供者(PROV_RSA_AES),而不是默认的一个.由于我有一个提供者句柄,我还需要用CryptGetUserKey替换CryptAcquireCertificatePrivateKey.所以我修改了我的程序,看起来像:
CryptAcquireContext (with PROV_RSA_AES)
CertOpenStore
CertFindCertificateInStore
CryptGetUserKey
CryptCreateHash (with CALG_SHA256)
CryptHashData
CryptSignHash
Run Code Online (Sandbox Code Playgroud)
不幸的是,这没有按预期工作:CryptGetUserKey失败,错误8009000D(NTE_NO_KEY).如果我删除了CryptGetUserKey调用,程序将一直运行,直到CryptSignHash失败,错误80090016(NTE_BAD_KEYSET).我知道密钥集确实存在并且工作正常,因为我能够使用它来签署SHA1摘要.
我尝试使用从CertFindCertificateInStore获得的证书上下文中的信息再次获取上下文:我能做的最好的是成功的CryptGetUserKey调用,但CryptSignHash总是会失败并出现相同的错误.
我试图使用的私钥是2048位长,但我不认为它是一个问题,因为它与SHA1摘要一起使用.我很茫然,所以任何建议都会非常受欢迎!
我有一个签名的DLL,并希望在我使用它之前验证它的签名.我的应用程序是由C++编写的.如何以编程方式获取dll的签名?
我想使用用户的密钥和来自USB令牌(加密狗)的证书来签署文件.
我一直在搜索stackoverflow和其他网站,但除了.NET框架中的一些好的功能(我没有使用)之外,它没有得到任何有用的东西.
似乎由于密钥未公开,加密由硬件本身完成.这是否意味着每个硬件制造商都提供自己的API,并且没有通用的方法来解决这个问题?
此外,我读到,一旦将令牌插入计算机,其证书就会被加载到系统存储中.是否可以使用商店的证书?如何在商店中识别和访问此类证书?私钥怎么样?
当证书可以从.p12或.pfx文件中提取时,我已经使用OpenSSL进行数字签名.
如果我在某个地方错了,请纠正我,我是这个话题的新手.
所以我做了一个小工具,一个控制台应用程序,当在Win7上运行时带来了安全盒(UAC).我尝试使用以下步骤在VS 2010中签署此EXE文件:
1-项目属性
2-签名
3-创建新密钥,如下所示

密钥文件已成功创建,您可以在下面的捕获中看到.

文件仍然被安全框阻止,当我使用signtool.exe检查文件是否签名时,它告诉我,没有找到签名.如果我遵循了错误的步骤,请纠正我.

请帮助我解决此代码中的歧义调用。
fac.newtransform()并fac.new signedinfo()给出错误信息:
参照
newTransform是模糊的,这两个方法newTransform(String,TransformParameterSpec)中XMLSignatureFactory和法newTransform(String,XMLStructure)在XMLSignatureFactory匹配
如何在中调用实际函数XMLSignatureFactory?
XMLSignatureFactory fac =XMLSignatureFactory.getInstance("DOM",
(Provider) Class.forName(providerName).newInstance());
Reference ref =fac.newReference("",fac.newDigestMethod(DigestMethod.SHA1, null),
Collections.singletonList(fac.newTransform(Transform.ENVELOPED, null)),null, null);
SignedInfo si = fac.newSignedInfo
(fac.newCanonicalizationMethod
(CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
null),
fac.newSignatureMethod(SignatureMethod.DSA_SHA1,
null),
Collections.singletonList(ref));
Run Code Online (Sandbox Code Playgroud) 一个collegue和我一直在试图了解如何JWT令牌验证令牌,但是从我们的阅读,我们似乎会混淆自己。
请有人可以帮助确认是否我的想法是正确的
我看了两个RS256和HS256并仍在努力确认了我的思维,因此后期的智威汤逊文档。