Spec-Zone .ru
спецификации, руководства, описания, API
|
GenSig
и VerSig
программы в этом уроке иллюстрируют использование API Безопасности JDK, чтобы генерировать цифровую подпись для данных и проверить, что подпись подлинна. Однако, фактический сценарий, изображенный теми программами, в которых отправитель использует API Безопасности JDK, чтобы генерировать новую пару "открытый/закрытый ключ", отправитель, хранит закодированные байты с открытым ключом в файле, и чтения получателя в ключевых байтах, не обязательно реалистичен, и имеет потенциальный главный дефект.
Во многих случаях ключи не должны быть сгенерированы; они уже существуют, или как закодированные ключи в файлах или как записи в keystore.
Потенциальный главный дефект - то, что ничто не гарантирует подлинности открытого ключа, который получатель получает, и VerSig
программа правильно проверяет подлинность подписи, только если открытый ключ, это предоставляется, самостоятельно подлинен!
Иногда закодировавшие ключевые байты уже существуют в файлах для пары ключей, которая будет использоваться для подписания и проверки. Если это так, GenSig
программа может импортировать закодированные байты с закрытым ключом и преобразовать их в a PrivateKey
необходимый для того, чтобы подписаться, через следующий, предполагая, что имя файла, содержащего байты с закрытым ключом, находится в privkeyfile
String
и что байты представляют ключ DSA, который был закодирован при использовании PKCS #8 стандарт.
FileInputStream keyfis = new FileInputStream(privkeyfile); byte[] encKey = new byte[keyfis.available()]; keyfis.read(encKey); keyfis.close(); PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(encKey); KeyFactory keyFactory = KeyFactory.getInstance("DSA"); PrivateKey privKey = keyFactory.generatePrivate(privKeySpec);
GenSig
больше потребности сохранить байты с открытым ключом в файле, как они уже находятся в одном.
В этом случае отправитель отправляет получатель
GenSig
. VerSig
программа остается неизменной, поскольку она уже ожидает закодированные байты с открытым ключом в файле.
Но что относительно потенциальной проблемы злонамеренного пользователя, прерывающего файлы и заменяющего их всех таким способом, которым не может быть обнаружен их переключатель? В некоторых случаях это не проблема, потому что люди уже обменивались открытыми ключами лицом к лицу или через доверенную третью сторону, которая делает обмен лицом к лицу. После того, как это, многократный последующий файл и обмены подписи могут быть сделаны удаленно (то есть, между двумя человеками в различных расположениях), и открытые ключи могут использоваться, чтобы проверить их подлинность. Если злонамеренный пользователь пытается изменить данные или подпись, это обнаруживается VerSig
.
Если ключевой обмен лицом к лицу не возможен, можно попробовать другие методы увеличения вероятности надлежащего получения. Например, Вы могли отправить свой открытый ключ через самый безопасный метод, возможный до последующих обменов данными и файлами подписи, возможно используя менее безопасные носители.
Вообще, отправка данных и подписи отдельно от Вашего открытого ключа значительно уменьшает вероятность атаки. Если все три файла не изменяются, и определенным способом, обсужденным в следующем абзаце, VerSig
обнаружит любое вмешательство.
Если бы все три файла (документ данных, открытый ключ, и подпись) были прерваны злонамеренным пользователем, то тот человек мог заменить документ чем-то еще, подписать его с закрытым ключом, и передать на Вас замененный документ, новую подпись, и открытый ключ, соответствующий закрытому ключу, используемому, чтобы генерировать новую подпись. Затем VerSig
сообщила бы успешная проверка, и Вы будете думать, что документ прибыл из исходного отправителя. Таким образом следует предпринять шаги, чтобы гарантировать, что, по крайней мере, открытый ключ получается неповрежденный (VerSig
обнаруживает любое вмешательство других файлов), или можно использовать сертификаты, чтобы облегчить аутентификацию открытого ключа, как описано в следующем разделе.
Более распространено в криптографии обмениваться сертификатами, содержащими открытые ключи, а не ключи непосредственно.
Одно преимущество - то, что сертификат подписывается одним объектом (выпускающий), чтобы проверить, что включенный открытый ключ является фактическим открытым ключом другого объекта (предмет или владелец). Обычно доверяемый сторонний центр сертификации (CA) проверяет идентификационные данные предмета и затем ручается за то, что это было владельцем открытого ключа, подписывая сертификат.
Другое преимущество использования сертификатов - то, что можно проверить, чтобы гарантировать законность сертификата Вы полученный, проверяя его цифровую подпись, используя открытый ключ (подписывающего лица) его выпускающего, который непосредственно может быть сохранен в сертификате, подпись которого может быть проверена при использовании открытого ключа того выпускающего сертификата; тот сам открытый ключ может быть сохранен в сертификате, и так далее, пока Вы не достигаете открытого ключа, которому Вы уже доверяете.
Если невозможно установить доверительную цепочку (возможно, потому что необходимые сертификаты выпускающего не доступны Вам), цифровой отпечаток (ки) сертификата может быть вычислен. Каждый цифровой отпечаток является относительно коротким числом, которое уникально и достоверно идентифицирует сертификат. (Технически это - значение хэш-функции информации о сертификате, используя обзор сообщения, также известный как односторонняя хэш-функция.) Вы можете призыв владелец сертификата и сравнивать цифровые отпечатки сертификата, который Вы получили с теми отправленными. Если они - то же самое, сертификаты являются тем же самым.
Это было бы более безопасно для GenSig
создать сертификат, содержащий открытый ключ и для VerSig
тогда импортировать сертификат и извлечь открытый ключ. Однако, у JDK нет никаких общедоступных API сертификата, которые позволили бы Вам создавать сертификат из открытого ключа, таким образом, GenSig
программа не может создать сертификат из открытого ключа, который она генерировала. (Есть общедоступные API для того, чтобы извлечь открытый ключ из сертификата, все же.)
Если Вы хотите, можно использовать различные средства обеспечения безопасности, не API, чтобы подписать Ваш важный документ (ы) и работу с сертификатами от keystore, как был сделан в уроке Файлов Обмена.
Альтернативно можно использовать API, чтобы изменить Ваши программы, чтобы работать с уже существующим и соответствующим открытым ключом с закрытым ключом (в сертификате) от Вашего keystore. Чтобы запустить, измените GenSig
программа, чтобы извлечь закрытый ключ из keystore, а не генерировать новые ключи. Во-первых, давайте принимать следующее:
String
ksName
spass
String
alias
kpass
Затем можно извлечь закрытый ключ из keystore через следующий.
KeyStore ks = KeyStore.getInstance("JKS"); FileInputStream ksfis = new FileInputStream(ksName); BufferedInputStream ksbufin = new BufferedInputStream(ksfis); ks.load(ksbufin, spass); PrivateKey priv = (PrivateKey) ks.getKey(alias, kpass);
Можно извлечь сертификат с открытым ключом из keystore и сохранить его закодированные байты к названному файлу suecert
, через следующий.
java.security.cert.Certificate cert = ks.getCertificate(alias); byte[] encodedCert = cert.getEncoded(); // Save the certificate in a file named "suecert" FileOutputStream certfos = new FileOutputStream("suecert"); certfos.write(encodedCert); certfos.close();
Затем Вы отправляете файл данных, подпись, и сертификат получателю. Получатель verifes подлинность сертификата первым получением цифровых отпечатков сертификата, через keytool -printcert
команда.
keytool -printcert -file suecert Owner: CN=Susan Jones, OU=Purchasing, O=ABC, L=Cupertino, ST=CA, C=US Issuer: CN=Susan Jones, OU=Purchasing, O=ABC, L=Cupertino, ST=CA, C=US Serial number: 35aaed17 Valid from: Mon Jul 13 22:31:03 PDT 1998 until: Sun Oct 11 22:31:03 PDT 1998 Certificate fingerprints: MD5: 1E:B8:04:59:86:7A:78:6B:40:AC:64:89:2C:0F:DD:13 SHA1: 1C:79:BD:26:A1:34:C0:0A:30:63:11:6A:F2:B9:67:DF:E5:8D:7B:5E
Затем получатель проверяет цифровые отпечатки, возможно звоня отправителю и сравнивая их с таковыми из сертификата отправителя или ища их в общедоступном репозитарии.
Программа проверки получателя (измененный VerSig
) может тогда импортировать сертификат и извлечь открытый ключ из этого через следующий, предполагая что имя файла сертификата (например, suecert
) находится в String
certName
.
FileInputStream certfis = new FileInputStream(certName); java.security.cert.CertificateFactory cf = java.security.cert.CertificateFactory.getInstance("X.509"); java.security.cert.Certificate cert = cf.generateCertificate(certfis); PublicKey pub = cert.getPublicKey();
Предположите, что Вы хотите сохранить содержание данных конфиденциальным, таким образом, люди случайно или злонамеренно пытающийся просмотреть их в пути (или на Вашей собственной машине или диске) не могут сделать так. Чтобы сохранить данные конфиденциальными, следует зашифровать это и сохранить и отправить только результат шифрования (называемый шифрованным текстом). Получатель может дешифровать шифрованный текст, чтобы получить копию исходных данных.