Я не знаю, как вы проверили подпись, кроме бессмысленной проверки в вашем коде, которая повторяет ошибку (и), но это были неверные данные, и поскольку вы не показали нам AlgoritmoAssinatura
может быть,неправильный метод.У вас также есть несколько других ошибок.Вместо того, чтобы подробно их описать, вот пример, который дает действительный результат с комментариями:
// use test data for example
KeyStore ks = KeyStore.getInstance("JKS"); ks.load(new FileInputStream (args[0]), args[1].toCharArray());
PrivateKey PrivKey = (PrivateKey) ks.getKey (args[2], args[1].toCharArray());
X509Certificate Certif = (X509Certificate) ks.getCertificate(args[2]);
String Message = "test";
String ArquivoAssinar = args[3];
String Charset = "ASCII"; // no idea, see below
String SrtResultPKCS7 = "";
byte[] Conteudo = Message.getBytes(Charset);
byte[] Hash;
//String DadosArq = "";
//String Linha = "";
//boolean AssinValid = false;
try {
// the name in SignerInfo is the _Issuer_ name NOT the Subject
X500Name xName = X500Name.asX500Name(Certif.getIssuerX500Principal());
BigInteger serial = Certif.getSerialNumber();
AlgorithmId digestAlgorithmId = new AlgorithmId(AlgorithmId.SHA_oid);
AlgorithmId signAlgorithmId = new AlgorithmId(AlgorithmId.RSAEncryption_oid);
MessageDigest MessDig = MessageDigest.getInstance("SHA1");
Hash = MessDig.digest(Conteudo);
PKCS9Attribute Atributo1 = new PKCS9Attribute(PKCS9Attribute.CONTENT_TYPE_OID, ContentInfo.DATA_OID);
PKCS9Attribute Atributo2 = new PKCS9Attribute(PKCS9Attribute.MESSAGE_DIGEST_OID, Hash);
PKCS9Attributes ConjuntoAtrib = new PKCS9Attributes(new PKCS9Attribute[] {Atributo1, Atributo2});
// when using signedattrs, signature is of the encoded attrs
// (without the context-implicit tag used when embedded in SignerInfo)
Signature Sign = Signature.getInstance("SHA1withRSA");
Sign.initSign(PrivKey);
Sign.update(ConjuntoAtrib.getDerEncoding());
byte[] ResultadoAssinatura = Sign.sign();
SignerInfo sInfo = new SignerInfo(xName, serial, digestAlgorithmId, ConjuntoAtrib, signAlgorithmId, ResultadoAssinatura, null);
// contenttype inside signed-data is data not digested-data
ContentInfo cInfo = new ContentInfo(ContentInfo.DATA_OID, new DerValue(DerValue.tag_OctetString, Conteudo));
PKCS7 p7 = new PKCS7(new AlgorithmId[] { digestAlgorithmId }, cInfo, new java.security.cert.X509Certificate[] { Certif }, new SignerInfo[] { sInfo });
ByteArrayOutputStream bOut = new DerOutputStream();
p7.encodeSignedData(bOut);
byte[] encoded = bOut.toByteArray();
// Java doesn't define a class 'Encoder' so I assume this is base64
SrtResultPKCS7 = DatatypeConverter.printBase64Binary(encoded); // gone in 11!
FileOutputStream Saida = new FileOutputStream(ArquivoAssinar);
OutputStreamWriter Escritor = new OutputStreamWriter(Saida, Charset);
BufferedWriter BuffWriter = new BufferedWriter(Escritor);
// this was correct for base64 (although the buffering is wasted)
BuffWriter.write(SrtResultPKCS7);
// this was nonsense -- it decodes the DER bytes as if they were characters,
// which they aren't, and then OSW re-encodes them to probably wrong bytes
//BuffWriter.write(bOut.toString());
BuffWriter.close();
// alternatively could write DER/binary with a Stream (NOT a Writer)
}
catch (Exception E) {
E.printStackTrace();
}
Мне не ясно, какой выходной формат вы - или сайт, на который вы ссылаетесь - хотите,Использование бинарных / DER довольно распространено, но не может быть вырезано и вставлено, и с ним сложнее работать.Base64 из DER встречается редко, но не неизвестно.Если вам или им нужен стандартный формат PEM, используемый многими программами, это НЕ просто base64 из DER;это base64 разрывов строк DER PLUS через каждые 64 символа, добавлены строки dash-BEGIN и dash-END.
Кроме того, SHA-1 был прерван из-за столкновения более года;см. https://shattered.io и многочисленные вопросы о криптографии. SX и security.SX об этом.Еще до этого он был запрещен для подписи многочисленными властями с 2014 или 2015 года, включая NIST (для правительства США) и CABforum (для публичных веб-сертификатов).Я ничего не знаю о данных, которые вы подписываете, но если они каким-либо образом важны или ценны, и у вас есть возможность использовать лучший хэш в своих сигнатурах, вам следует.
ДОБАВЛЕНО: также, как я полагаю, вы понимаете, что sun.*
классы не документированы, не гарантированы и могут перестать работать в любое время, когда Oracle захочет.