using (var fileStream = new MemoryStream())
{
using (var stamper = PdfStamper.CreateSignature(reader, fileStream, '0', null, true))
{
var signatureAppearance = stamper.SignatureAppearance;
signatureAppearance.SetVisibleSignature(new iTextSharp.text.Rectangle(15,15,15,15), 1, "A");
IExternalSignatureContainer external =
new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
signatureAppearance.Reason = "AsdAsd";
signatureAppearance.Layer2Text = "Asd";
signatureAppearance.SignatureRenderingMode =
iTextSharp.text.pdf.PdfSignatureAppearance.RenderingMode.DESCRIPTION;
MakeSignature.SignExternalContainer(signatureAppearance, external, 512);
return fileStream.ToArray();
}
}
let pdfBuffer = Buffer.from(new Uint8Array(pdf));
const byteRangeString = `/ByteRange `;
const byteRangePos = pdfBuffer.indexOf(byteRangeString);
if (byteRangePos === -1)
throw new Error('asd');
let len = pdfBuffer.slice(byteRangePos).indexOf(`]`) + 1;
// Calculate the actual ByteRange that needs to replace the placeholder.
const byteRangeEnd = byteRangePos + len;
const contentsTagPos = pdfBuffer.indexOf('/Contents ', byteRangeEnd);
const placeholderPos = pdfBuffer.indexOf('<', contentsTagPos);
const placeholderEnd = pdfBuffer.indexOf('>', placeholderPos);
const placeholderLengthWithBrackets = placeholderEnd + 1 - placeholderPos;
const placeholderLength = placeholderLengthWithBrackets - 2;
const byteRange = [0, 0, 0, 0];
byteRange[1] = placeholderPos;
byteRange[2] = byteRange[1] + placeholderLengthWithBrackets;
byteRange[3] = pdfBuffer.length - byteRange[2];
let actualByteRange = `/ByteRange [${byteRange.join(' ')}]`;
actualByteRange += ' '.repeat(len - actualByteRange.length);
// Replace the /ByteRange placeholder with the actual ByteRange
pdfBuffer = Buffer.concat([pdfBuffer.slice(0, byteRangePos) as any, Buffer.from(actualByteRange), pdfBuffer.slice(byteRangeEnd)]);
// Remove the placeholder signature
pdfBuffer = Buffer.concat([pdfBuffer.slice(0, byteRange[1]) as any, pdfBuffer.slice(byteRange[2], byteRange[2] + byteRange[3])]);
和
//stringSignature comes from the signature creations below, and is 'hex' encoded
// Pad the signature with zeroes so the it is the same length as the placeholder
stringSignature += Buffer
.from(String.fromCharCode(0).repeat((placeholderLength / 2) - len))
.toString('hex');
// Place it in the document.
pdfBuffer = Buffer.concat([
pdfBuffer.slice(0, byteRange[1]) as any,
Buffer.from(`<${stringSignature}>`),
pdfBuffer.slice(byteRange[1])
]);
==typeof CryptoKey
,forge抛出一个错误:TypeError:signer.key.sign不是函数
)
p7.addCertificate(certificate); //certificate is the Certificate from Fortify CertificateStore.getItem(certId)
p7.addSigner({
key: privateKey, //this is the CryptoKey from Fortify
certificate: null/*certificate*/, //also tried certificate from Fortify
digestAlgorithm: forge.pki.oids.sha256,
authenticatedAttributes: [
{
type: forge.pki.oids.contentType,
value: forge.pki.oids.data,
}, {
type: forge.pki.oids.messageDigest,
// value will be auto-populated at signing time
}, {
type: forge.pki.oids.signingTime,
// value can also be auto-populated at signing time
// We may also support passing this as an option to sign().
// Would be useful to match the creation time of the document for example.
value: new Date(),
},
],
});
// Sign in detached mode.
p7.sign({detached: true});
Signing error:TypeError:未能在'sublecrypto'上执行'sign':参数2不是'CryptoKey'类型。
)let cmsSigned = new pki.SignedData({
encapContentInfo: new pki.EncapsulatedContentInfo({
eContentType: "1.2.840.113549.1.7.1", // "data" content type
eContent: new asn.OctetString({ valueHex: pdfBuffer })
}),
signerInfos: [
new pki.SignerInfo({
sid: new pki.IssuerAndSerialNumber({
issuer: certificate.issuer,
serialNumber: certificate.serialNumber
})
})
],
certificates: [certificate]
});
let signature = await cmsSigned.sign(privateKey, 0, 'SHA-256');
let signature = await provider.subtle.sign(alg, privateKey, new Uint8Array(pdfBuffer).buffer);
“有效”,因为它创建了无效的签名:
签名验证期间出错<阿斯恩。1解析错误:
BER解码时遇到错误:
我尝试了多个证书,没有运气。
CrytpoKey
转换为伪造或pkijs吗?谢谢: F
所以我想出来了。
我能在不需要手动上传p12/pfx文件的情况下实现我的目标吗?
是的。(有关需要更改的内容,请参见下文。)
延迟签名的服务器端实现是否正确,是否需要其他内容?
是的,上面的代码很好。
javascript中的pdf操作正确吗?
也很好。
我可以将本机CrytpoKey转换为伪造或pkijs吗?
是的,见下文。
最后一个签名有什么问题?
@mkl在评论中回答了一下,谢谢。
FortifyApp现在有一个CMS演示。虽然它不适用于我使用的版本,但它适用于版本1.3.4。
所以我选择了pki。js实现。签名成功所需的代码更改如下:
const cryptoCert = await provider.certStorage.getItem(selectedCertificateId);
const certRawData = await provider.certStorage.exportCert('raw', cryptoCert);
const pkiCert = new pki.Certificate({
schema: asn.fromBER(certRawData).result,
});
return pkiCert;
let cmsSigned = new pki.SignedData({
version: 1,
encapContentInfo: new pki.EncapsulatedContentInfo({
eContentType: '1.2.840.113549.1.7.1',
}),
signerInfos: [
new pki.SignerInfo({
version: 1,
sid: new pki.IssuerAndSerialNumber({
issuer: certificate.issuer,
serialNumber: certificate.serialNumber
})
})
],
certificates: [certificate]
});
let signature = await cmsSigned.sign(privateKey, 0, 'SHA-256', pdfBuffer);
const cms = new pki.ContentInfo({
contentType: '1.2.840.113549.1.7.2',
content: cmsSigned.toSchema(true),
});
const result = cms.toSchema().toBER(false);
return result;
let stringSignature = Array.prototype.map.call(new Uint8Array(signature), x => (`00${x.toString(16)}`).slice(-2)).join('');
let len = signature.byteLength;
问题内容: 我正在尝试在我的网站上部署Java applet。我还需要签名,因为我需要访问剪贴板。我遵循了所有可以找到但没有成功的签名教程。到目前为止,这是我所做的: 在NetBeans中编写了一个applet。它在applet查看器中运行良好。 从中制作一个.jar文件。 通过执行以下操作创建证书: 像这样用jarsigner签名: 制作了一个包含以下内容的html文件: 当我打开该html文件
现在相信很多团队的代码都是直接用 ES2015+ 语法来编写和维护,然后通过 Babel 将 ES2015+ 语法转成支持老浏览器的 js 代码,经过转换后的 js 代码从体积和解析执行效率上都比转换前有损耗。 兼容性 从 Caniuse 网站的数据来看,现在绝大多数的浏览器已经对 ES2015+有了很好的支持,而经过我们统计百度 APP 的 Webview 浏览器数据来看,国内大概有 74.71
问题内容: 是否仍然可以通过浏览器中的Java小程序在Windows下启动“本机”应用程序?IE在网页上“单击此处以启动notepad.exe”。我为此找到的最新参考文献是2002年。我想知道是否不再支持该模型/概念。 问题答案: 是的,但是必须签署小程序。 签名的小程序将提示用户授予他们权限。一旦指定了applet,它就具有与计算机上运行的任何应用程序相同的权限,包括启动本机应用程序(或链接本机
本文向大家介绍js判断浏览器版本以及浏览器内核的方法,包括了js判断浏览器版本以及浏览器内核的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了js判断浏览器版本以及浏览器内核的方法。分享给大家供大家参考。具体实现方法如下: js判断是否移动端及浏览器内核 代码二 希望本文所述对大家的javascript程序设计有所帮助。
我试图在用户拍照时检测相机方向,以便在画布上绘制时进行调整。问题是我不能使用设备方向,因为即使方向锁定打开,我也需要它才能工作。 摄像机设置 视频流快照 来自David Walsh的参考代码 - 浏览器摄像头
认识到React本机应用程序设计为使用模拟器开发/测试,是否可以使用web浏览器也测试应用程序? 服务,例如https://rnplay.org/ 存在,但我担心的是它是由https://appetize.io/ 它可能受到每月分钟数的限制。与付费的屏幕流媒体服务相比,我还想利用免费/开源技术来实现这一点。 按照这些思路,为了在浏览器中测试应用程序,应用程序是否需要使用一个或多个库,这些库允许应用