Last active
July 20, 2018 14:40
-
-
Save REDNBLACK/a84971af32c42b2e40674b4dd5563952 to your computer and use it in GitHub Desktop.
PKPass/Passbook Signing in Scala and Java with native PCKS7 and sun.security
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.security.cert.X509Certificate | |
import java.security.{MessageDigest, PrivateKey, Signature} | |
import java.util.Date | |
import sun.security.pkcs.ContentInfo.DATA_OID | |
import sun.security.pkcs.PKCS9Attribute.{CONTENT_TYPE_OID, MESSAGE_DIGEST_OID, SIGNING_TIME_OID} | |
import sun.security.pkcs._ | |
import sun.security.util.DerOutputStream | |
import sun.security.x509.{AlgorithmId, X500Name} | |
object PKPassSigner { | |
val DigestAlgorithmId = new AlgorithmId(AlgorithmId.SHA_oid) | |
val SignatureAlgorithmId = new AlgorithmId(AlgorithmId.sha1WithRSAEncryption_oid) | |
val ContentInfo = new ContentInfo(DATA_OID, null) | |
def sign( | |
signingCert: X509Certificate, | |
privateKey: PrivateKey, | |
intermediateCert: X509Certificate, | |
dataToSing: Array[Byte] | |
): Array[Byte] = { | |
val attributes = new PKCS9Attributes(Array( | |
new PKCS9Attribute(SIGNING_TIME_OID, new Date()), | |
new PKCS9Attribute( | |
MESSAGE_DIGEST_OID, | |
MessageDigest.getInstance(DigestAlgorithmId.getName).digest(dataToSign) | |
), | |
new PKCS9Attribute(CONTENT_TYPE_OID, DATA_OID) | |
)) | |
val signature = Signature.getInstance(SignatureAlgorithmId.getName) | |
signature.initSign(privateKey) | |
signature.update(attributes.getDerEncoding) | |
val signerInfo = new SignerInfo( | |
X500Name.asX500Name(signingCert.getIssuerX500Principal), | |
signingCert.getSerialNumber, | |
DigestAlgorithmId, | |
attributes, | |
AlgorithmId.get(privateKey.getAlgorithm), | |
signature.sign(), | |
null | |
) | |
val p7 = new PKCS7( | |
Array(DigestAlgorithmId), | |
ContentInfo, | |
Array(signingCert, intermediateCert), | |
Array(signerInfo) | |
) | |
val out = new DerOutputStream() | |
try { | |
p7.encodeSignedData(out) | |
out.toByteArray | |
} finally { | |
out.close() | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment