Андрей * написал:как без привязки... ? Зачем тогда ЭЦП, если я могу менять данные, а ЭЦП остается валидной!
Потому что ЭЦП сама в себе содержит какие-то атрибуты, которым она должна соответствовать. И в примере они оттуда вынимаются, а потом проверяется, что ЭЦП им соответствует. Мне это тоже кажется бессмысленным... Конечно, я мог что-то не так понять, это весьма вероятно. И если я это неправильно понял, а ты мне объяснишь как правильно - это будет даже очень хорошо! :)
Андрей * написал:Как? Опиши алгоритм, очень интересно! Очень убедительные слова...
Описать алгоритм я затрудняюсь. Но вот код примера, который мне посоветовали посмотреть:
Пример из samples_src.jar\CMS_samples написал:
public static void main(String[] args) throws Exception {
//данные для проверки (CMS)
final byte[] signdata = Array.readFile(CMS_FILE_PATH);
// final Certificate cert = CMStools.loadCertificate(CMStools.SIGN_KEY_NAME);
//Certificate cert = CMStools.readCertificate(CMStools.SIGN_CERT_PATH);
//проверка
final Certificate[] certs = new Certificate[1];
certs[0] = CMStools.loadCertificate(CMStools.SIGN_KEY_NAME);
CMSVerify(signdata, certs, null);
}
/**
* проверка CMS
*
* @param buffer буфер
* @param certs сертификаты
* @param data данные
* @throws Exception e
*/
public static void CMSVerify(byte[] buffer, Certificate[] certs, byte[] data)
throws Exception {
//clear buffers fo logs
out = new StringBuffer("");
out1 = new StringBuffer("");
final Asn1BerDecodeBuffer asnBuf = new Asn1BerDecodeBuffer(buffer);
final ContentInfo all = new ContentInfo();
all.decode(asnBuf);
if (!new OID(CMStools.STR_CMS_OID_SIGNED).eq(all.contentType.value))
throw new Exception("Not supported");
final SignedData cms = (SignedData) all.content;
final byte[] text;
if (cms.encapContentInfo.eContent != null)
text = cms.encapContentInfo.eContent.value;
else if (data != null) text = data;
else throw new Exception("No content for verify");
OID digestOid = null;
final DigestAlgorithmIdentifier digestAlgorithmIdentifier =
new DigestAlgorithmIdentifier(new OID(CMStools.DIGEST_OID).value);
for (int i = 0; i < cms.digestAlgorithms.elements.length; i++) {
if (cms.digestAlgorithms.elements[i].algorithm
.equals(digestAlgorithmIdentifier.algorithm)) {
digestOid =
new OID(cms.digestAlgorithms.elements[i].algorithm.value);
break;
}
}
if (digestOid == null)
throw new Exception("Unknown digest");
final OID eContTypeOID = new OID(cms.encapContentInfo.eContentType.value);
if (cms.certificates != null) {
//Проверка на вложенных сертификатах
CMStools.logger.info("Validation on certificates founded in CMS.");
for (int i = 0; i < cms.certificates.elements.length; i++) {
final Asn1BerEncodeBuffer encBuf = new Asn1BerEncodeBuffer();
cms.certificates.elements[i].encode(encBuf);
final CertificateFactory cf =
CertificateFactory.getInstance("X.509");
final X509Certificate cert =
(X509Certificate) cf
.generateCertificate(encBuf.getInputStream());
for (int j = 0; j < cms.signerInfos.elements.length; j++) {
final SignerInfo info = cms.signerInfos.elements[j];
if (!digestOid
.equals(new OID(info.digestAlgorithm.algorithm.value)))
throw new Exception("Not signed on certificate.");
final boolean checkResult = verifyOnCert(cert,
cms.signerInfos.elements[j], text, eContTypeOID);
writeLog(checkResult, j, i, cert);
}
}
} else if (certs != null) {
//Проверка на указанных сертификатах
CMStools.logger.info("Certificates for validation not found in CMS.\n" +
" Try verify on specified certificates...");
for (int i = 0; i < certs.length; i++) {
final X509Certificate cert = (X509Certificate) certs[i];
for (int j = 0; j < cms.signerInfos.elements.length; j++) {
final SignerInfo info = cms.signerInfos.elements[j];
if (!digestOid.equals(new OID(
info.digestAlgorithm.algorithm.value)))
throw new Exception("Not signed on certificate.");
final boolean checkResult = verifyOnCert(cert,
cms.signerInfos.elements[j], text, eContTypeOID);
writeLog(checkResult, j, i, cert);
}
}
} else {
CMStools.logger.warning("Certificates for validation not found");
}
if (validsign == 0) throw new Exception("Signatures are invalid" + out1);
if (cms.signerInfos.elements.length > validsign)
throw new Exception("Some signatures are invalid:" + out + out1);
else CMStools.logger.info("All signatures are valid:" + out);
}
Как видим, в этом примере метод CMSVerify(signdata, certs, null) вызывается с null вместо реальных данных, соответствующих подписи. И тем не менее, чего-то там внутри верифицируется, правильно? Внутри этого метода мы видим:
final Asn1BerDecodeBuffer asnBuf = new Asn1BerDecodeBuffer(buffer);
final ContentInfo all = new ContentInfo();
all.decode(asnBuf);
final SignedData cms = (SignedData) all.content;
final byte[] text;
if (cms.encapContentInfo.eContent != null)
text = cms.encapContentInfo.eContent.value;
И дальше все верификация крутится вокруг этого массива text, который получен из самой подписи.
Вот я попробовал этот метод запустить для моей сгенерированной плагином подписи, которая соответствует строке "Message". Так вот в этой получившейся подписи cms.encapContentInfo.eContent.value != "Message".getBytes() :( И я не знаю, как мне установить соответствие между получившейся подписью и строкой "Message"
Отредактировано пользователем 26 сентября 2012 г. 0:15:24(UTC)
| Причина: Не указана