ошибка генерации подписанного CSR с помощью javacard (значение неправильного тега asn1)

Я сгенерировал пару ключей на java-карте и вернул открытый ключ. Я снова генерирую открытый ключ в приложении для Android, а затем CSR в Android.

 private byte[] CertReqGeneration()  throws Exception
 {
    if(publickeyobj==null)
        return null;

    String info = "CN=cn, OU=ou, O=o, C=cn, ST=city";
    X500Principal x500 = new X500Principal(info);

    X500Name x500name;
    x500name= X500Name.getInstance(x500.getEncoded());

    CertificationRequestInfo csrInfo = new CertificationRequestInfo(x500name, publickeyobj, new DERSet());

    ASN1EncodableVector v = new ASN1EncodableVector();
    v.add(csrInfo);
    ASN1ObjectIdentifier oid = new ASN1ObjectIdentifier("0.0");
    v.add(new DERSequence(oid));
    v.add(new DERBitString(new byte[] {}));
    byte[] encoded = new DERSequence(v).getEncoded();
    byte[] PKCS10= DataSignGeneration(encoded);

       byte[] encoded = Base64.encode(PKCS10);
      String base64=new String(encoded);
    return  base64;

}

но когда я хочу выпустить его в ca, я получаю сообщение об ошибке asn1 bad tag value met 0x8009310b

Это мой код для входа в апплет:

  //sign
      Signature signature=Signature.getInstance(Signature.ALG_RSA_SHA_PKCS1,false);
      signature.init(thePrivateKey,Signature.MODE_SIGN);
      signLength=signature.sign(buffer,(short)(ISO7816.OFFSET_CDATA & 0xFF), inputlength, buffer, (short)(0));

это подписанный csr, который сгенерировал мой код

G1Xsg/fetpr1/RfbUzWmDqRqu2GvymoQwXUJS/tB36l1SAvrRyDtwCgVHB3ukYFSZJeavFISQ9+R4zD1qxjO6r/E2/3o9UfARm2GeTwEZFv8LVgULAPc/e64v5xkiQYO05QwHa5PtmaXXD4NtuSNvF9xgNjtdAkosKqEPLcme5k=

person Fatemeh    schedule 23.10.2016    source источник
comment
Спасибо, мистер Абрахам. Должен ли я просмотреть формат pkcs # 10?   -  person Fatemeh    schedule 24.10.2016
comment
Спасибо, дорогой pedrofb, за редактирование моего вопроса.   -  person Fatemeh    schedule 25.10.2016


Ответы (3)


Анализ @Abraham кажется правильным: сгенерированный контент CSR недействителен

Я предполагаю, что целью этого кода является создание структуры ASN.1 для подписи, но bouncycastle сделает это за вас.

ASN1EncodableVector v = new ASN1EncodableVector();
v.add(csrInfo);
ASN1ObjectIdentifier oid = new ASN1ObjectIdentifier("0.0");
v.add(new DERSequence(oid));
v.add(new DERBitString(new byte[] {}));
byte[] encoded = new DERSequence(v).getEncoded();
byte[] PKCS10= DataSignGeneration(encoded);

После комментариев мы видим, что необходимо создать неподписанный запрос PKCS10 для отправки на javacard для подписи там, и получить результат для построения подписанного запроса PKCS10.

Bouncycastle не предоставляет API для выполнения операции. Я предлагаю проверить PKCS10 и исходный код PKCS10CertificateRequestBuilder для адаптации к использованию вашей карты Java. Если вы хотите использовать в Android, вам нужен специальный дистрибутив spongycastle.

Это рабочий пример для создания неподписанного запроса (без java-карты, но его легко адаптировать. Просто процесс подписи)

public byte[] generateCSR (X500Name subject, PublicKey publicKey, String signatureAlgorithm) throws Exception{
    //Create the unsigned CSR
    CertificationRequestInfo info = new CertificationRequestInfo(
                    x500name, SubjectPublicKeyInfo.getInstance(publicKey.getEncoded()),new DERSet());

    //The CSR bytes to be signed
    byte dataToSign[] = info.getEncoded(ASN1Encoding.DER);

    //Send the CSR to the card
    byte signedData[] = signOnJavaCard (dataToSign,signatureAlgorithm);

    //Build the signed CSR
    AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find(signatureAlgorithm);
    PKCS10CertificationRequest csr = new PKCS10CertificationRequest(
                    new CertificationRequest(info, sigAlgId, new DERBitString(signedData)));
    byte signedCSR = csr.getEncoded();

    //Verify signature validity
    ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().setProvider(new BouncyCastleProvider()).build(publicKey);
    boolean valid = csr.isSignatureValid(verifier);

    return signedCSR;
}

Для проверки кода я использовал локальный метод подписи.

public byte signOnJavaCard (byte dataToSign[], String signatureAlgorithm)
    Signature signature = Signature.getInstance(signatureAlgorithm);
    signature.initSign(privateKey); //get the private key in some way...
    signature.update(dataToSign);
    return signature.sign();
}
person pedrofb    schedule 24.10.2016
comment
Если вы хотите отправить некоторые данные на карту Javacard (данные для подписи в данном случае), вам нужно поместить их в структуру, называемую командой APDU. Команда APDU состоит из фиксированного 5-байтового заголовка и необязательного тела данных. Индекс 5 в вопросе связан с фиксированным заголовком. - person Ebrahim Ghasemi; 24.10.2016
comment
Из-за аппаратных ограничений оборудования Javacard они не поддерживают многие библиотеки и возможности Java. Например, они обычно не поддерживают тип int. Для javacards нет библиотеки надувных замков. - person Ebrahim Ghasemi; 24.10.2016
comment
Хорошо, @Abraham, понял OFFSET_CDATA. Bouncycastle используется в коде Android, только вы должны отправить на карту операцию подписи через API Bouncycastle - person pedrofb; 24.10.2016
comment
Большое спасибо. но мне нужен неподписанный запрос pkcs # 10, потому что я должен подписать его закрытым ключом в java-карте. я использую этот код. не так ли?блог .pastelstudios.com/2015/04/21/ - person Fatemeh; 24.10.2016
comment
Я не знаю, что это правильно, но это неполно. В нем не объясняется, какие данные должны быть подписаны и как создать подписанный запрос CSR. Лучший вариант — посмотреть исходный код bouncycastle. Какую версию ты используешь? - person pedrofb; 24.10.2016
comment
Я использую spongycastle. В этом коде pkcs10 равен UnsignedPkcs10CertificationRequest. Должен ли я подписать его закрытым ключом для создания Pkcs10CertificationRequest? - person Fatemeh; 24.10.2016
comment
Извините... использую scprov-jdk15on-1.47.0.2 - person Fatemeh; 24.10.2016
comment
Я включил полный пример с использованием 1.49 (последний код в bouncycastle github), чтобы создать неподписанный CSR, получить байты для подписи и построить окончательный CSR. Вероятно, это работает и с 1.47 (если нет, проверьте исходный код). Не знаю откуда взялся код блога, но в коде БК его нет - person pedrofb; 24.10.2016
comment
Можете ли вы дать мне кодовый адрес на github? Я подпишу csr. как построить окончательный CSR? - person Fatemeh; 24.10.2016
comment
Я включил ссылку в ответ. Используйте new PKCS10CertificationRequest(new CertificationRequest(info, sigAlgId, new DERBitString(signedData))); Вы можете увидеть это в ответе - person pedrofb; 24.10.2016
comment
Извините... Я получаю сообщение об ошибке при новом DefaultSignatureAlgorithmIdentifierFinder().find(SHA1withRSA) и моя программа останавливается - person Fatemeh; 24.10.2016
comment
Это проблема с библиотекой. Убедитесь, что у вас есть зависимости SC, или попробуйте эту альтернативу sigAlgId = new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.2.840.113549.1.1.5")) для SHA1WithRsa. - person pedrofb; 24.10.2016
comment
Заранее спасибо. Он работает хорошо, и csr генерируется. но я должен опустить ContentVerifierProvider verifier = new JcaContentVerifierProviderBuilder().setProvider(new BouncyCastleProvider() ).build(currentpublickey); логическое значение действительное = csr.isSignatureValid (верификатор); У меня ошибка. Можете ли вы сказать мне, что такое SC Dendencies? - person Fatemeh; 24.10.2016
comment
простите..понял. да, я добавил SC dendencies. я прикрепил их к моему вопросу - person Fatemeh; 25.10.2016
comment
Извините, что я это переписал. и я выполнил логическое значение valid = csr.isSignatureValid(verifier); но действительное значение ложно. Я использую Signature.ALG_RSA_SHA_PKCS1 для подписи. Я не уверен. Это rsa с sha1? - person Fatemeh; 25.10.2016
comment
Это тот же алгоритм sha1withrsa. Если проверка не удалась, это означает, что подписанные данные не соответствуют подписываемому сообщению или открытому ключу. Вероятно, вы неправильно отправляете или получаете данные на карту. Проверьте свой код подписи и добавьте проверку подписи, прежде чем возвращать результат. - person pedrofb; 25.10.2016
comment
Простите уважаемый педроб. Можете ли вы помочь мне с этой ссылкой stackoverflow.com /вопросы/40725518/ - person Fatemeh; 21.11.2016

Давайте сначала взглянем на ваш сгенерированный CSR. Я использую онлайн-декодер ASN.1.

Что ж, онлайн-инструмент не расшифрует ваш CSR. ТАК это недействительно:

введите описание изображения здесь

Хорошо, давайте посмотрим, как выглядит действующий CSR. Я сгенерировал CSR с помощью OpenSSL:

ghasemi@ghasemi-MS-7693:~$ openssl genrsa -out priv.key 1024
Generating RSA private key, 1024 bit long modulus
............................++++++
.......................++++++
e is 65537 (0x10001)
ghasemi@ghasemi-MS-7693:~$ ls
priv.key
ghasemi@ghasemi-MS-7693:~$ openssl req -new -key priv.key -out my_csr.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:IR 
State or Province Name (full name) [Some-State]:Tehran
Locality Name (eg, city) []:Tehran
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Company
Organizational Unit Name (eg, section) []:Section
Common Name (e.g. server FQDN or YOUR name) []:Ebrahim
Email Address []:ebr.ghasemi at gmail 

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

ghasemi@ghasemi-MS-7693:~$ ls
my_csr.csr  priv.key

Как вы видите выше, я сгенерировал CSR с 1024-битной парой ключей. Позвольте увидеть содержание:

ghasemi@ghasemi-MS-7693:~$ cat my_csr.csr 
-----BEGIN CERTIFICATE REQUEST-----
MIIByzCCATQCAQAwgYoxCzAJBgNVBAYTAklSMQ8wDQYDVQQIDAZUZWhyYW4xDzAN
BgNVBAcMBlRlaHJhbjEQMA4GA1UECgwHQ29tcGFueTEQMA4GA1UECwwHU2VjdGlv
bjEQMA4GA1UEAwwHRWJyYWhpbTEjMCEGCSqGSIb3DQEJARYUZWJyLmdoYXNlbWkg
YXQgZ21haWwwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOJK2YUOSREjrDbZ
auC3/509NOAL+xjqJ2x947CtSIyuPSLuplDW4oAkvaqYvA5ocIxeAGbW9WZF/OdM
8z5XoQF3+ogGsEna1TZN1TY5XOdrRgIu9gFA2KRNPjnEZIkt7FLBJUQlk5aithk4
lfy73XCoosjWUwBOKac5ZIKOuXEHAgMBAAGgADANBgkqhkiG9w0BAQsFAAOBgQCF
hQzkAgfongzP9EKV+oTwVhqkQ7bfy5TE85YIR3aymuzbvAc9KWdWydOxHiHqXbmZ
ECWvLlMsrlrpyDO2Xxy8UXFJkNgH4Rys267ETaoYh19htc4qZzNqK/1ejQBUidgY
QoafJxv3YhO+gYr2txyxPRN0etcquElwx0odF8KBVA==
-----END CERTIFICATE REQUEST-----
ghasemi@ghasemi-MS-7693:~$ 

Ну, очевидное отличие — это длина, начальная и конечная линии. Мой CSR действительно больше, чем ваш. Он начинается с -----BEGIN CERTIFICATE REQUEST----- и заканчивается на -----END CERTIFICATE REQUEST-----.

Проверим его содержимое декодером ASN.1:

введите описание изображения здесь

Хорошо. Как видите, символы, которые я ввел при генерации CSR, есть внутри CSR в виде обычного текста, а не в вашем.

Так что же не так?

Ваш апплет возвращает только подпись вашей информации CSR. Это не CSR, это только его Подпись. Таким образом, вы должны сгенерировать CSR с информацией CSR и подписью. Кроме того, открытый ключ, используемый в CSR Info, ДОЛЖЕН быть открытым ключом, который его закрытый ключ используется для создания подписи, в противном случае CA не сможет проверить действительность CSR и расценит ваш CSR как поддельный / поддельный CSR. .

Итак, после создания KeyPair внутри карты экспортируйте открытый ключ в приложение для Android. а затем сгенерируйте информацию CSR и сгенерируйте подпись этой информации внутри карты, а затем, используя информацию CSR и подпись, создайте свой CSR.

person Ebrahim Ghasemi    schedule 24.10.2016
comment
Спасибо. Как вы видите в моем коде, я сделал все, как вы сказали. Я получил открытый ключ с карты и заново сгенерировал открытый ключ в Android. Я думаю, что я должен добавить csr + подпись csr (оба из них) в asn1. Это правильно? - person Fatemeh; 24.10.2016

Эта ошибка, по-видимому, означает, что закрытый ключ (созданный при запросе сертификата) не соответствует открытому ключу (файлу .crt). Пара ключей не присоединена к рабочему SSL-сертификату.

Решение. Начните с импорта файла .crt в хранилище персональных сертификатов на локальном компьютере. (Кнопка «Пуск» > «Выполнить»: MMC > «Меню файлов» > «Добавить/удалить оснастку» > выделите оснастку «Сертификаты» и нажмите кнопку «ДОБАВИТЬ» > выберите «Учетная запись компьютера» и нажмите «Готово» > нажмите «ОК» > перейдите в раздел «Личные» > «Сертификаты» > щелкните правой кнопкой мыши и выберите Все задачи> выберите «Импорт»> руководство по файлу .crt.) На этом этапе ваш сертификат в основном представляет собой полусертификат. У него все еще отсутствует закрытый ключ.

Во-вторых, дважды щелкните файл сертификата crt, который вы только что импортировали, выберите вкладку «Подробности», прокрутите до конца и выделите «Отпечаток». В нижней панели заблокируйте и скопируйте все буквы отпечатка. Вставьте символы отпечатка в блокнот. Откройте командную строку и выполните следующую команду: Certutil /?

Команда, которую вы хотите запустить:

certutil -repairstore my «{вставьте сюда все символы отпечатка}»

Когда вы увидите ответ: «Команда CertUtil: -repairstore успешно выполнена», у вас должен быть закрытый ключ, связанный с файлом .crt в личном хранилище. Больше не нужно запускать мастер «Завершить запрос сертификата…». На этом этапе сертификат должен отображаться в списке сертификатов сервера диспетчера IIS. Он также должен быть доступен в раскрывающемся списке SSL-сертификаты при попытке изменить привязку https для веб-сайта.

Ссылка: https://blogs.msdn.microsoft.com/webtopics/2009/01/03/asn1-bad-tag-value-met-error-when-processing-a-certificate-request-in-iis-7/

person Malik Mumtaz    schedule 24.10.2016
comment
Спасибо за ответ. Я сгенерировал пару ключей на java-карте. Почему ssl?? Я думаю, что плохой csr генерируется. но я написал свой код здесь. Я не понимаю, где я могу ошибиться в созданной паре ключей? - person Fatemeh; 24.10.2016
comment
Хорошо, но попробуйте связать открытый и закрытый ключи так, чтобы пара ключей успешно соединилась. Ошибка неправильного значения тега возникает, когда нет никакой связи между сгенерированной парой ключей. - person Malik Mumtaz; 24.10.2016
comment
Большое спасибо. Но я хочу создать карту, и эта работа выполняется автоматически. - person Fatemeh; 24.10.2016