Как сгенерировать CSR вручную в JavaJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Как сгенерировать CSR вручную в Java

Сообщение Anonymous »

Я пытаюсь сгенерировать запрос на подпись сертификата (CSR) на Java без использования сторонних библиотек, таких как BouncyCastle. Ниже приведен код, который я использую для создания CSR:

Код: Выделить всё

public void createCSR(@NonNull KeyPair keyPair, @NonNull CSRCallback csrCallback) {
try {
byte[] subject = encodeSubject("CN=MyClient, O=MyOrganization, L=City, C=US");
byte[] publicKey = encodePublicKey(keyPair.getPublic());
byte[] algorithmIdentifier = encodeAlgorithmIdentifier();
byte[] dataToSign = concatenateData(subject, publicKey, algorithmIdentifier);
byte[] signature = signData(dataToSign, keyPair.getPrivate());
byte[] csrBytes = createCSR(subject, publicKey, algorithmIdentifier, signature);
String pemCSR = toPEM(csrBytes);

csrCallback.onCSRGenerated(pemCSR);
} catch (Exception e) {
csrCallback.onCSRGenerationFailed(e);
}
}

byte[] encodeSubject(String subjectDN) throws Exception {
// Example subject: "CN=MyClient, O=MyOrganization, L=City, C=US"
String[] rdnPairs = subjectDN.split(",\\s*");
ByteArrayOutputStream subjectStream = new ByteArrayOutputStream();

for (String rdn : rdnPairs) {
String[] keyValue = rdn.split("=");
String rdnType = keyValue[0];
String rdnValue = keyValue[1];

ByteArrayOutputStream rdnStream = new ByteArrayOutputStream();
rdnStream.write(0x0C); // UTF8String tag
rdnStream.write(rdnValue.length());
rdnStream.write(rdnValue.getBytes(StandardCharsets.UTF_8));

ByteArrayOutputStream rdnPairStream = new ByteArrayOutputStream();
rdnPairStream.write(0x31); // SET tag
rdnPairStream.write(rdnStream.size());
rdnPairStream.write(rdnStream.toByteArray());

subjectStream.write(0x30); // SEQUENCE tag
subjectStream.write(rdnPairStream.size());
subjectStream.write(rdnPairStream.toByteArray());
}

ByteArrayOutputStream finalSubjectStream = new ByteArrayOutputStream();
finalSubjectStream.write(0x30); // SEQUENCE tag
finalSubjectStream.write(subjectStream.size());
finalSubjectStream.write(subjectStream.toByteArray());

return finalSubjectStream.toByteArray();
}

byte[] encodePublicKey(PublicKey publicKey) {
return publicKey.getEncoded(); // Returns the public key in X.509 DER format
}

byte[] encodeAlgorithmIdentifier() {
// OID for RSA encryption (1.2.840.113549.1.1.11 for SHA256withRSA)
return new byte[]{
0x30, 0x0D, 0x06, 0x09,
0x2A, (byte) 0x86, 0x48, (byte) 0x86, (byte) 0xF7, 0x0D, 0x01, 0x01, 0x0B, // OID for SHA256withRSA
0x05, 0x00 // NULL parameter
};
}

byte[] concatenateData(byte[] subject, byte[] publicKey, byte[] algorithmIdentifier) throws Exception {
ByteArrayOutputStream data = new ByteArrayOutputStream();
data.write(subject);
data.write(publicKey);
data.write(algorithmIdentifier);
return data.toByteArray();
}

byte[] signData(byte[] data, PrivateKey privateKey) throws Exception {
Signature signature = Signature.getInstance("SHA256withRSA/PSS");
signature.initSign(privateKey);
signature.update(data);
return signature.sign();
}

byte[] createCSR(byte[] subject, byte[] publicKey, byte[] algorithmIdentifier, byte[] signature) throws Exception {
ByteArrayOutputStream csrStream = new ByteArrayOutputStream();

// SEQUENCE for CSR
csrStream.write(0x30);
int startPos = csrStream.size(); // Save the position for length

// Version: INTEGER 0
csrStream.write(0x02); // INTEGER tag
csrStream.write(0x01); // Length
csrStream.write(0x00); // Version value

// Subject
csrStream.write(subject);

// Public Key Info
csrStream.write(publicKey);

// Signature Algorithm
csrStream.write(algorithmIdentifier);

// Signature
csrStream.write(0x03); // BIT STRING tag
csrStream.write(signature.length + 1); // Length
csrStream.write(0x00); // Unused bits
csrStream.write(signature);

// Update the length field
byte[] csrBytes = csrStream.toByteArray();
int length = csrBytes.length - startPos;
csrBytes[startPos - 1] = (byte) length;

return csrBytes;
}

String toPEM(byte[] csrBytes) {
String base64CSR = Base64.getMimeEncoder(64, "\n".getBytes()).encodeToString(csrBytes);
return "-----BEGIN CERTIFICATE REQUEST-----\n"  + base64CSR + "\n-----END CERTIFICATE REQUEST-----";
}
Сгенерированный сертификат

Код: Выделить всё

-----BEGIN CERTIFICATE REQUEST-----
cQIBADA0MAwxCgwITXlDbGllbnQwEjEQDA5NeU9yZ2FuaXphdGlvbjAIMQYMBENp
dHkwBjEEDAJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALjePfuq
/FCzB5TE9A6oq6BOGEEufqHmU0Xsn93bG8Hk5YoShnFQ4GwW9z1+NPoc+1RZOpfT
TlIxd7lHb86q5vvq6AhZ9nvtxkkQ491A3aZHJwQD2w3q8/6JH/8h7kPzGLnqsmUb
2oTfIeIcQXCdlKg2QI6BocB1I0HdrycFYTkYfVlUIgsrNx+8Vu09QsX1BahqGs/C
Jkl+Xs30nwMBC3buVYW5Nk5fM5z/fDQW+nJBCtJhXFiu4czedCx0YcPaY/W0tkj3
4SELBjr7aaWORy1Wa9jeLMyc63s8JCst7vl+/otEKoBL8sRVrOozlz+rWwalCWbs
QiF9pc/JeCYSEgMCAwEAATANBgkqhkiG9w0BAQsFAAMBAKfAVIwcl6rWYHKo/KYq
ikFjoyjxMRL6NuB0K85TaNeJTUyPL6gD2qkbepEbIzpq0useQTLgXPq4XGkiVK+0
Ey/E+wzStiYcJXNIu/CxTodz+Jnc7KNIus6GbaVNybh4hUOK1MVPmsuXv1eJuus7
xiaTEgMkEYd9K5yfOU6ZEFaRnpT89VJQrD92AaC7GhIR6n0ZM5z7YG5h3upNah5a
vlEG5alWd/hCxouML3TaOKaq5UjVN51FoOuNCjUHzJr6hzZc3nUPwS9slE8FZyHg
5kwTxIAJ84WdDrG+m0cTG+MNnqmazkzeHNqf6QEH/xecQd6MDliftvXUJe8H2N0O
LA0=
-----END CERTIFICATE REQUEST-----
когда я запускаю: openssl req -in request.csr -noout -text
то получаю ошибку ниже:

Код: Выделить всё

C08F6E51F87F0000:error:068000A8:asn1 encoding routines:asn1_check_tlen:wrong tag:crypto/asn1/tasn_dec.c:1194:
C08F6E51F87F0000:error:0688010A:asn1 encoding routines:asn1_item_embed_d2i:nested asn1 error:crypto/asn1/tasn_dec.c:349:Type=X509_REQ
error: unable to load X509 request from file 'request.csr'
Мой код генерации пары ключей —

Код: Выделить всё

public static KeyPair generateRSAKeyPairWithAuth(String alias) throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
keyGen.initialize(new KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
.setAlgorithmParameterSpec(new RSAKeyGenParameterSpec(2048, RSAKeyGenParameterSpec.F4))
.setUserAuthenticationRequired(true)
.setUserAuthenticationValidityDurationSeconds(120)
.setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1, KeyProperties.SIGNATURE_PADDING_RSA_PSS)
.setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512).build());
return keyGen.generateKeyPair();
}
ПРИМЕЧАНИЕ. Я не хочу использовать для этого BouncyCastle или SpongyCastle.

Подробнее здесь: https://stackoverflow.com/questions/792 ... ly-in-java
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»