下面列出了java.util.jar.JarException#sun.security.pkcs.SignerInfo 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
static void checkTimestamp(String file, String policyId, String digestAlg)
throws Exception {
try (JarFile jf = new JarFile(file)) {
JarEntry je = jf.getJarEntry("META-INF/SIGNER.RSA");
try (InputStream is = jf.getInputStream(je)) {
byte[] content = IOUtils.readAllBytes(is);
PKCS7 p7 = new PKCS7(content);
SignerInfo[] si = p7.getSignerInfos();
if (si == null || si.length == 0) {
throw new Exception("Not signed");
}
PKCS9Attribute p9 = si[0].getUnauthenticatedAttributes()
.getAttribute(PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID);
PKCS7 tsToken = new PKCS7((byte[]) p9.getValue());
TimestampToken tt =
new TimestampToken(tsToken.getContentInfo().getData());
if (!tt.getHashAlgorithm().toString().equals(digestAlg)) {
throw new Exception("Digest alg different");
}
if (!tt.getPolicyID().equals(policyId)) {
throw new Exception("policyId different");
}
}
}
}
static void checkTimestamp(String file, String policyId, String digestAlg)
throws Exception {
try (JarFile jf = new JarFile(file)) {
JarEntry je = jf.getJarEntry("META-INF/SIGNER.RSA");
try (InputStream is = jf.getInputStream(je)) {
byte[] content = IOUtils.readAllBytes(is);
PKCS7 p7 = new PKCS7(content);
SignerInfo[] si = p7.getSignerInfos();
if (si == null || si.length == 0) {
throw new Exception("Not signed");
}
PKCS9Attribute p9 = si[0].getUnauthenticatedAttributes()
.getAttribute(PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID);
PKCS7 tsToken = new PKCS7((byte[]) p9.getValue());
TimestampToken tt =
new TimestampToken(tsToken.getContentInfo().getData());
if (!tt.getHashAlgorithm().toString().equals(digestAlg)) {
throw new Exception("Digest alg different");
}
if (!tt.getPolicyID().equals(policyId)) {
throw new Exception("policyId different");
}
}
}
}
/** Write the certificate file with a digital signature. */
private void writeSignatureBlock(Signature signature, X509Certificate publicKey,
PrivateKey privateKey)
throws IOException, GeneralSecurityException {
SignerInfo signerInfo = new SignerInfo(
new X500Name(publicKey.getIssuerX500Principal().getName()),
publicKey.getSerialNumber(),
AlgorithmId.get(DIGEST_ALGORITHM),
AlgorithmId.get(privateKey.getAlgorithm()),
signature.sign());
PKCS7 pkcs7 = new PKCS7(
new AlgorithmId[] { AlgorithmId.get(DIGEST_ALGORITHM) },
new ContentInfo(ContentInfo.DATA_OID, null),
new X509Certificate[] { publicKey },
new SignerInfo[] { signerInfo });
pkcs7.encodeSignedData(mOutputJar);
}
/** Write the certificate file with a digital signature. */
private void writeSignatureBlock(Signature signature, X509Certificate publicKey,
PrivateKey privateKey)
throws IOException, GeneralSecurityException {
SignerInfo signerInfo = new SignerInfo(
new X500Name(publicKey.getIssuerX500Principal().getName()),
publicKey.getSerialNumber(),
AlgorithmId.get(DIGEST_ALGORITHM),
AlgorithmId.get(privateKey.getAlgorithm()),
signature.sign());
PKCS7 pkcs7 = new PKCS7(
new AlgorithmId[] { AlgorithmId.get(DIGEST_ALGORITHM) },
new ContentInfo(ContentInfo.DATA_OID, null),
new X509Certificate[] { publicKey },
new SignerInfo[] { signerInfo });
pkcs7.encodeSignedData(mOutputJar);
}
static void checkTimestamp(String file, String policyId, String digestAlg)
throws Exception {
try (JarFile jf = new JarFile(file)) {
JarEntry je = jf.getJarEntry("META-INF/SIGNER.RSA");
try (InputStream is = jf.getInputStream(je)) {
byte[] content = IOUtils.readAllBytes(is);
PKCS7 p7 = new PKCS7(content);
SignerInfo[] si = p7.getSignerInfos();
if (si == null || si.length == 0) {
throw new Exception("Not signed");
}
PKCS9Attribute p9 = si[0].getUnauthenticatedAttributes()
.getAttribute(PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID);
PKCS7 tsToken = new PKCS7((byte[]) p9.getValue());
TimestampToken tt =
new TimestampToken(tsToken.getContentInfo().getData());
if (!tt.getHashAlgorithm().toString().equals(digestAlg)) {
throw new Exception("Digest alg different");
}
if (!tt.getPolicyID().equals(policyId)) {
throw new Exception("policyId different");
}
}
}
}
/**
* Write the certificate file with a digital signature.
*/
private void writeSignatureBlock(Signature signature, X509Certificate publicKey,
PrivateKey privateKey)
throws IOException, GeneralSecurityException {
SignerInfo signerInfo = new SignerInfo(
new X500Name(publicKey.getIssuerX500Principal().getName()),
publicKey.getSerialNumber(),
AlgorithmId.get(DIGEST_ALGORITHM),
AlgorithmId.get(privateKey.getAlgorithm()),
signature.sign());
PKCS7 pkcs7 = new PKCS7(
new AlgorithmId[]{AlgorithmId.get(DIGEST_ALGORITHM)},
new ContentInfo(ContentInfo.DATA_OID, null),
new X509Certificate[]{publicKey},
new SignerInfo[]{signerInfo});
pkcs7.encodeSignedData(mOutputJar);
}
static void checkTimestamp(String file, String policyId, String digestAlg)
throws Exception {
try (JarFile jf = new JarFile(file)) {
JarEntry je = jf.getJarEntry("META-INF/OLD.RSA");
try (InputStream is = jf.getInputStream(je)) {
byte[] content = IOUtils.readFully(is, -1, true);
PKCS7 p7 = new PKCS7(content);
SignerInfo[] si = p7.getSignerInfos();
if (si == null || si.length == 0) {
throw new Exception("Not signed");
}
PKCS9Attribute p9 = si[0].getUnauthenticatedAttributes()
.getAttribute(PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID);
PKCS7 tsToken = new PKCS7((byte[]) p9.getValue());
TimestampToken tt =
new TimestampToken(tsToken.getContentInfo().getData());
if (!tt.getHashAlgorithm().toString().equals(digestAlg)) {
throw new Exception("Digest alg different");
}
if (!tt.getPolicyID().equals(policyId)) {
throw new Exception("policyId different");
}
}
}
}
/** Write the certificate file with a digital signature. */
private void writeSignatureBlock(Signature signature, X509Certificate publicKey,
PrivateKey privateKey)
throws IOException, GeneralSecurityException {
SignerInfo signerInfo = new SignerInfo(
new X500Name(publicKey.getIssuerX500Principal().getName()),
publicKey.getSerialNumber(),
AlgorithmId.get(DIGEST_ALGORITHM),
AlgorithmId.get(privateKey.getAlgorithm()),
signature.sign());
PKCS7 pkcs7 = new PKCS7(
new AlgorithmId[] { AlgorithmId.get(DIGEST_ALGORITHM) },
new ContentInfo(ContentInfo.DATA_OID, null),
new X509Certificate[] { publicKey },
new SignerInfo[] { signerInfo });
pkcs7.encodeSignedData(mOutputJar);
}
static void checkTimestamp(String file, String policyId, String digestAlg)
throws Exception {
try (JarFile jf = new JarFile(file)) {
JarEntry je = jf.getJarEntry("META-INF/OLD.RSA");
try (InputStream is = jf.getInputStream(je)) {
byte[] content = is.readAllBytes();
PKCS7 p7 = new PKCS7(content);
SignerInfo[] si = p7.getSignerInfos();
if (si == null || si.length == 0) {
throw new Exception("Not signed");
}
PKCS9Attribute p9 = si[0].getUnauthenticatedAttributes()
.getAttribute(PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID);
PKCS7 tsToken = new PKCS7((byte[]) p9.getValue());
TimestampToken tt =
new TimestampToken(tsToken.getContentInfo().getData());
if (!tt.getHashAlgorithm().toString().equals(digestAlg)) {
throw new Exception("Digest alg different");
}
if (!tt.getPolicyID().equals(policyId)) {
throw new Exception("policyId different");
}
}
}
}
static void checkTimestamp(String file, String policyId, String digestAlg)
throws Exception {
try (JarFile jf = new JarFile(file)) {
JarEntry je = jf.getJarEntry("META-INF/OLD.RSA");
try (InputStream is = jf.getInputStream(je)) {
byte[] content = IOUtils.readFully(is, -1, true);
PKCS7 p7 = new PKCS7(content);
SignerInfo[] si = p7.getSignerInfos();
if (si == null || si.length == 0) {
throw new Exception("Not signed");
}
PKCS9Attribute p9 = si[0].getUnauthenticatedAttributes()
.getAttribute(PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID);
PKCS7 tsToken = new PKCS7((byte[]) p9.getValue());
TimestampToken tt =
new TimestampToken(tsToken.getContentInfo().getData());
if (!tt.getHashAlgorithm().toString().equals(digestAlg)) {
throw new Exception("Digest alg different");
}
if (!tt.getPolicyID().equals(policyId)) {
throw new Exception("policyId different");
}
}
}
}
static void checkTimestamp(String file, String policyId, String digestAlg)
throws Exception {
try (JarFile jf = new JarFile(file)) {
JarEntry je = jf.getJarEntry("META-INF/OLD.RSA");
try (InputStream is = jf.getInputStream(je)) {
byte[] content = IOUtils.readFully(is, -1, true);
PKCS7 p7 = new PKCS7(content);
SignerInfo[] si = p7.getSignerInfos();
if (si == null || si.length == 0) {
throw new Exception("Not signed");
}
PKCS9Attribute p9 = si[0].getUnauthenticatedAttributes()
.getAttribute(PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID);
PKCS7 tsToken = new PKCS7((byte[]) p9.getValue());
TimestampToken tt =
new TimestampToken(tsToken.getContentInfo().getData());
if (!tt.getHashAlgorithm().toString().equals(digestAlg)) {
throw new Exception("Digest alg different");
}
if (!tt.getPolicyID().equals(policyId)) {
throw new Exception("policyId different");
}
}
}
}
static void checkTimestamp(String file, String policyId, String digestAlg)
throws Exception {
try (JarFile jf = new JarFile(file)) {
JarEntry je = jf.getJarEntry("META-INF/SIGNER.RSA");
try (InputStream is = jf.getInputStream(je)) {
byte[] content = IOUtils.readAllBytes(is);
PKCS7 p7 = new PKCS7(content);
SignerInfo[] si = p7.getSignerInfos();
if (si == null || si.length == 0) {
throw new Exception("Not signed");
}
PKCS9Attribute p9 = si[0].getUnauthenticatedAttributes()
.getAttribute(PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID);
PKCS7 tsToken = new PKCS7((byte[]) p9.getValue());
TimestampToken tt =
new TimestampToken(tsToken.getContentInfo().getData());
if (!tt.getHashAlgorithm().toString().equals(digestAlg)) {
throw new Exception("Digest alg different");
}
if (!tt.getPolicyID().equals(policyId)) {
throw new Exception("policyId different");
}
}
}
}
/** Write the certificate file with a digital signature. */
private void writeSignatureBlock(Signature signature, X509Certificate publicKey,
PrivateKey privateKey)
throws IOException, GeneralSecurityException {
SignerInfo signerInfo = new SignerInfo(
new X500Name(publicKey.getIssuerX500Principal().getName()),
publicKey.getSerialNumber(),
AlgorithmId.get(DIGEST_ALGORITHM),
AlgorithmId.get(privateKey.getAlgorithm()),
signature.sign());
PKCS7 pkcs7 = new PKCS7(
new AlgorithmId[] { AlgorithmId.get(DIGEST_ALGORITHM) },
new ContentInfo(ContentInfo.DATA_OID, null),
new X509Certificate[] { publicKey },
new SignerInfo[] { signerInfo });
pkcs7.encodeSignedData(mOutputJar);
}
/**
* Verifies that the signature computed from {@code sfBytes} matches
* that specified in {@code blockBytes} (which is a PKCS7 block). Returns
* certificates listed in the PKCS7 block. Throws a {@code GeneralSecurityException}
* if something goes wrong during verification.
*/
static Certificate[] verifyBytes(byte[] blockBytes, byte[] sfBytes)
throws GeneralSecurityException {
Object obj = null;
try {
obj = Providers.startJarVerification();
PKCS7 block = new PKCS7(blockBytes);
SignerInfo[] verifiedSignerInfos = block.verify(sfBytes);
if ((verifiedSignerInfos == null) || (verifiedSignerInfos.length == 0)) {
throw new GeneralSecurityException(
"Failed to verify signature: no verified SignerInfos");
}
// Ignore any SignerInfo other than the first one, to be compatible with older Android
// platforms which have been doing this for years. See
// libcore/luni/src/main/java/org/apache/harmony/security/utils/JarUtils.java
// verifySignature method of older platforms.
SignerInfo verifiedSignerInfo = verifiedSignerInfos[0];
List<X509Certificate> verifiedSignerCertChain =
verifiedSignerInfo.getCertificateChain(block);
if (verifiedSignerCertChain == null) {
// Should never happen
throw new GeneralSecurityException(
"Failed to find verified SignerInfo certificate chain");
} else if (verifiedSignerCertChain.isEmpty()) {
// Should never happen
throw new GeneralSecurityException(
"Verified SignerInfo certificate chain is emtpy");
}
return verifiedSignerCertChain.toArray(
new X509Certificate[verifiedSignerCertChain.size()]);
} catch (IOException e) {
throw new GeneralSecurityException("IO exception verifying jar cert", e);
} finally {
Providers.stopJarVerification(obj);
}
}
/**
* Encode the CertPath using PKCS#7 format.
*
* @return a byte array containing the binary encoding of the PKCS#7 object
* @exception CertificateEncodingException if an exception occurs
*/
private byte[] encodePKCS7() throws CertificateEncodingException {
PKCS7 p7 = new PKCS7(new AlgorithmId[0],
new ContentInfo(ContentInfo.DATA_OID, null),
certs.toArray(new X509Certificate[certs.size()]),
new SignerInfo[0]);
DerOutputStream derout = new DerOutputStream();
try {
p7.encodeSignedData(derout);
} catch (IOException ioe) {
throw new CertificateEncodingException(ioe.getMessage());
}
return derout.toByteArray();
}
/**
* Given the PKCS7 block and SignerInfo[], create an array of
* CodeSigner objects. We do this only *once* for a given
* signature block file.
*/
private CodeSigner[] getSigners(SignerInfo[] infos, PKCS7 block)
throws IOException, NoSuchAlgorithmException, SignatureException,
CertificateException {
ArrayList<CodeSigner> signers = null;
for (int i = 0; i < infos.length; i++) {
SignerInfo info = infos[i];
ArrayList<X509Certificate> chain = info.getCertificateChain(block);
CertPath certChain = certificateFactory.generateCertPath(chain);
if (signers == null) {
signers = new ArrayList<>();
}
// Append the new code signer. If timestamp is invalid, this
// jar will be treated as unsigned.
signers.add(new CodeSigner(certChain, info.getTimestamp()));
if (debug != null) {
debug.println("Signature Block Certificate: " +
chain.get(0));
}
}
if (signers != null) {
return signers.toArray(new CodeSigner[signers.size()]);
} else {
return null;
}
}
public static void main(String[] args) throws Exception {
byte[] data = "Hello".getBytes();
X500Name n = new X500Name("cn=Me");
CertAndKeyGen cakg = new CertAndKeyGen("RSA", "SHA256withRSA");
cakg.generate(1024);
X509Certificate cert = cakg.getSelfCertificate(n, 1000);
MessageDigest md = MessageDigest.getInstance("SHA-256");
PKCS9Attributes authed = new PKCS9Attributes(new PKCS9Attribute[]{
new PKCS9Attribute(PKCS9Attribute.CONTENT_TYPE_OID, ContentInfo.DATA_OID),
new PKCS9Attribute(PKCS9Attribute.MESSAGE_DIGEST_OID, md.digest(data)),
});
Signature s = Signature.getInstance("SHA256withRSA");
s.initSign(cakg.getPrivateKey());
s.update(authed.getDerEncoding());
byte[] sig = s.sign();
SignerInfo signerInfo = new SignerInfo(
n,
cert.getSerialNumber(),
AlgorithmId.get("SHA-256"),
authed,
AlgorithmId.get("SHA256withRSA"),
sig,
null
);
PKCS7 pkcs7 = new PKCS7(
new AlgorithmId[] {signerInfo.getDigestAlgorithmId()},
new ContentInfo(data),
new X509Certificate[] {cert},
new SignerInfo[] {signerInfo});
if (pkcs7.verify(signerInfo, data) == null) {
throw new Exception("Not verified");
}
}
static void printSignerInfos(SignerInfo signerInfo) throws IOException {
ByteArrayOutputStream strm = new ByteArrayOutputStream();
signerInfo.derEncode(strm);
System.out.println("SignerInfo, length: "
+ strm.toByteArray().length);
System.out.println(hexDump.encode(strm.toByteArray()));
System.out.println("\n");
strm.reset();
}
static void printSignerInfos(SignerInfo[] signerInfos) throws IOException {
ByteArrayOutputStream strm = new ByteArrayOutputStream();
for (int i = 0; i < signerInfos.length; i++) {
signerInfos[i].derEncode(strm);
System.out.println("SignerInfo[" + i + "], length: "
+ strm.toByteArray().length);
System.out.println(hexDump.encode(strm.toByteArray()));
System.out.println("\n");
strm.reset();
}
}
/**
* Encode the CertPath using PKCS#7 format.
*
* @return a byte array containing the binary encoding of the PKCS#7 object
* @exception CertificateEncodingException if an exception occurs
*/
private byte[] encodePKCS7() throws CertificateEncodingException {
PKCS7 p7 = new PKCS7(new AlgorithmId[0],
new ContentInfo(ContentInfo.DATA_OID, null),
certs.toArray(new X509Certificate[certs.size()]),
new SignerInfo[0]);
DerOutputStream derout = new DerOutputStream();
try {
p7.encodeSignedData(derout);
} catch (IOException ioe) {
throw new CertificateEncodingException(ioe.getMessage());
}
return derout.toByteArray();
}
/**
* Given the PKCS7 block and SignerInfo[], create an array of
* CodeSigner objects. We do this only *once* for a given
* signature block file.
*/
private CodeSigner[] getSigners(SignerInfo[] infos, PKCS7 block)
throws IOException, NoSuchAlgorithmException, SignatureException,
CertificateException {
ArrayList<CodeSigner> signers = null;
for (int i = 0; i < infos.length; i++) {
SignerInfo info = infos[i];
ArrayList<X509Certificate> chain = info.getCertificateChain(block);
CertPath certChain = certificateFactory.generateCertPath(chain);
if (signers == null) {
signers = new ArrayList<>();
}
// Append the new code signer. If timestamp is invalid, this
// jar will be treated as unsigned.
signers.add(new CodeSigner(certChain, info.getTimestamp()));
if (debug != null) {
debug.println("Signature Block Certificate: " +
chain.get(0));
}
}
if (signers != null) {
return signers.toArray(new CodeSigner[signers.size()]);
} else {
return null;
}
}
public static void main(String[] args) throws Exception {
byte[] data = "Hello".getBytes();
X500Name n = new X500Name("cn=Me");
CertAndKeyGen cakg = new CertAndKeyGen("RSA", "SHA256withRSA");
cakg.generate(1024);
X509Certificate cert = cakg.getSelfCertificate(n, 1000);
MessageDigest md = MessageDigest.getInstance("SHA-256");
PKCS9Attributes authed = new PKCS9Attributes(new PKCS9Attribute[]{
new PKCS9Attribute(PKCS9Attribute.CONTENT_TYPE_OID, ContentInfo.DATA_OID),
new PKCS9Attribute(PKCS9Attribute.MESSAGE_DIGEST_OID, md.digest(data)),
});
Signature s = Signature.getInstance("SHA256withRSA");
s.initSign(cakg.getPrivateKey());
s.update(authed.getDerEncoding());
byte[] sig = s.sign();
SignerInfo signerInfo = new SignerInfo(
n,
cert.getSerialNumber(),
AlgorithmId.get("SHA-256"),
authed,
AlgorithmId.get("SHA256withRSA"),
sig,
null
);
PKCS7 pkcs7 = new PKCS7(
new AlgorithmId[] {signerInfo.getDigestAlgorithmId()},
new ContentInfo(data),
new X509Certificate[] {cert},
new SignerInfo[] {signerInfo});
if (pkcs7.verify(signerInfo, data) == null) {
throw new Exception("Not verified");
}
}
static void printSignerInfos(SignerInfo signerInfo) throws IOException {
ByteArrayOutputStream strm = new ByteArrayOutputStream();
signerInfo.derEncode(strm);
System.out.println("SignerInfo, length: "
+ strm.toByteArray().length);
System.out.println(hexDump.encode(strm.toByteArray()));
System.out.println("\n");
strm.reset();
}
static void printSignerInfos(SignerInfo[] signerInfos) throws IOException {
ByteArrayOutputStream strm = new ByteArrayOutputStream();
for (int i = 0; i < signerInfos.length; i++) {
signerInfos[i].derEncode(strm);
System.out.println("SignerInfo[" + i + "], length: "
+ strm.toByteArray().length);
System.out.println(hexDump.encode(strm.toByteArray()));
System.out.println("\n");
strm.reset();
}
}
/**
* Encode the CertPath using PKCS#7 format.
*
* @return a byte array containing the binary encoding of the PKCS#7 object
* @exception CertificateEncodingException if an exception occurs
*/
private byte[] encodePKCS7() throws CertificateEncodingException {
PKCS7 p7 = new PKCS7(new AlgorithmId[0],
new ContentInfo(ContentInfo.DATA_OID, null),
certs.toArray(new X509Certificate[certs.size()]),
new SignerInfo[0]);
DerOutputStream derout = new DerOutputStream();
try {
p7.encodeSignedData(derout);
} catch (IOException ioe) {
throw new CertificateEncodingException(ioe.getMessage());
}
return derout.toByteArray();
}
public static void main(String[] args) throws Exception {
byte[] data = "Hello".getBytes();
X500Name n = new X500Name("cn=Me");
CertAndKeyGen cakg = new CertAndKeyGen("RSA", "SHA256withRSA");
cakg.generate(1024);
X509Certificate cert = cakg.getSelfCertificate(n, 1000);
MessageDigest md = MessageDigest.getInstance("SHA-256");
PKCS9Attributes authed = new PKCS9Attributes(new PKCS9Attribute[]{
new PKCS9Attribute(PKCS9Attribute.CONTENT_TYPE_OID, ContentInfo.DATA_OID),
new PKCS9Attribute(PKCS9Attribute.MESSAGE_DIGEST_OID, md.digest(data)),
});
Signature s = Signature.getInstance("SHA256withRSA");
s.initSign(cakg.getPrivateKey());
s.update(authed.getDerEncoding());
byte[] sig = s.sign();
SignerInfo signerInfo = new SignerInfo(
n,
cert.getSerialNumber(),
AlgorithmId.get("SHA-256"),
authed,
AlgorithmId.get("SHA256withRSA"),
sig,
null
);
PKCS7 pkcs7 = new PKCS7(
new AlgorithmId[] {signerInfo.getDigestAlgorithmId()},
new ContentInfo(data),
new X509Certificate[] {cert},
new SignerInfo[] {signerInfo});
if (pkcs7.verify(signerInfo, data) == null) {
throw new Exception("Not verified");
}
}
/**
* Encode the CertPath using PKCS#7 format.
*
* @return a byte array containing the binary encoding of the PKCS#7 object
* @exception CertificateEncodingException if an exception occurs
*/
private byte[] encodePKCS7() throws CertificateEncodingException {
PKCS7 p7 = new PKCS7(new AlgorithmId[0],
new ContentInfo(ContentInfo.DATA_OID, null),
certs.toArray(new X509Certificate[certs.size()]),
new SignerInfo[0]);
DerOutputStream derout = new DerOutputStream();
try {
p7.encodeSignedData(derout);
} catch (IOException ioe) {
throw new CertificateEncodingException(ioe.getMessage());
}
return derout.toByteArray();
}
/**
* Given the PKCS7 block and SignerInfo[], create an array of
* CodeSigner objects. We do this only *once* for a given
* signature block file.
*/
private CodeSigner[] getSigners(SignerInfo[] infos, PKCS7 block)
throws IOException, NoSuchAlgorithmException, SignatureException,
CertificateException {
ArrayList<CodeSigner> signers = null;
for (int i = 0; i < infos.length; i++) {
SignerInfo info = infos[i];
ArrayList<X509Certificate> chain = info.getCertificateChain(block);
CertPath certChain = certificateFactory.generateCertPath(chain);
if (signers == null) {
signers = new ArrayList<>();
}
// Append the new code signer. If timestamp is invalid, this
// jar will be treated as unsigned.
signers.add(new CodeSigner(certChain, info.getTimestamp()));
if (debug != null) {
debug.println("Signature Block Certificate: " +
chain.get(0));
}
}
if (signers != null) {
return signers.toArray(new CodeSigner[signers.size()]);
} else {
return null;
}
}
public static void main(String[] args) throws Exception {
byte[] data = "Hello".getBytes();
X500Name n = new X500Name("cn=Me");
CertAndKeyGen cakg = new CertAndKeyGen("RSA", "SHA256withRSA");
cakg.generate(1024);
X509Certificate cert = cakg.getSelfCertificate(n, 1000);
MessageDigest md = MessageDigest.getInstance("SHA-256");
PKCS9Attributes authed = new PKCS9Attributes(new PKCS9Attribute[]{
new PKCS9Attribute(PKCS9Attribute.CONTENT_TYPE_OID, ContentInfo.DATA_OID),
new PKCS9Attribute(PKCS9Attribute.MESSAGE_DIGEST_OID, md.digest(data)),
});
Signature s = Signature.getInstance("SHA256withRSA");
s.initSign(cakg.getPrivateKey());
s.update(authed.getDerEncoding());
byte[] sig = s.sign();
SignerInfo signerInfo = new SignerInfo(
n,
cert.getSerialNumber(),
AlgorithmId.get("SHA-256"),
authed,
AlgorithmId.get("SHA256withRSA"),
sig,
null
);
PKCS7 pkcs7 = new PKCS7(
new AlgorithmId[] {signerInfo.getDigestAlgorithmId()},
new ContentInfo(data),
new X509Certificate[] {cert},
new SignerInfo[] {signerInfo});
if (pkcs7.verify(signerInfo, data) == null) {
throw new Exception("Not verified");
}
}
static void printSignerInfos(SignerInfo signerInfo) throws IOException {
ByteArrayOutputStream strm = new ByteArrayOutputStream();
signerInfo.derEncode(strm);
System.out.println("SignerInfo, length: "
+ strm.toByteArray().length);
System.out.println(hexDump.encode(strm.toByteArray()));
System.out.println("\n");
strm.reset();
}