Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

266
Vistas
¿Por qué mis claves SHA512-ECDSA, generadas en bouncycastle, no coinciden en jsrsasign?

Tengo una aplicación y un servidor que usan mensajes firmados (usando bouncycastle) para comunicarse. Para una nueva aplicación, quiero usar JS y firmar el mensaje usando jsrsasign y luego verificarlo en el lado del servidor usando bouncycastle nuevamente. Las claves también se generan en bouncycastle y luego se transfieren a la aplicación JS.

La firma siempre es inválida para la comunicación JS->Server, así que traté de firmar y verificar el mensaje completamente en JS y descubrí que esto tampoco funciona. Asumo que no estoy usando la configuración correcta, pero no logro descifrar el origen del problema.

Estoy usando ECDSA con la curva prime256v1.

Mis claves se generan así:

 val generator = KeyPairGenerator.getInstance("ECDSA") val spec = ECNamedCurveTable.getParameterSpec("prime256v1") generator.initialize(spec, SecureRandom()) val keypair = generator.generateKeyPair() val privateKey = Base64.toBase64String(keypair.private.encoded) // X962 val publicKey = Base64.toBase64String(Arrays.copyOfRange(keypair.public.encoded, 26, keypair.public.encoded.size))

Las claves generadas se ven así:

 privateKey = MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQg6xrOGWvvTTh5EfxhDco0xqppyFrSRbFaKUKbZutlynugCgYIKoZIzj0DAQehRANCAAQ6EhELaQWv3z7tBgJXYMGspw93Ni+LvvmY3f0MSBtu84ldBZi3boz+OV3hiiyO+mBx+jCg4s2TDF+nw0Vi3lS7 publicKey = BDoSEQtpBa/fPu0GAldgwaynD3c2L4u++Zjd/QxIG27ziV0FmLdujP45XeGKLI76YHH6MKDizZMMX6fDRWLeVLs=

Para probar, tomo estas claves y ejecuto esto para ver si son válidas en el lado de JS:

 const message = "Testing"; // Sign const sig = new KJUR.crypto.Signature({ alg: "SHA512withECDSA" }); sig.init({ d: keyPair.private, curve: "prime256v1" }); sig.updateString(message); const signature = sig.sign(); // Verify let sigVerification = new r.Signature({ alg: "SHA512withECDSA" }); sigVerification.init({ xy: keyPair.public, curve: "prime256v1" }); sigVerification.updateString(message); let isValid = sigVerification.verify(signature); if(isValid) { console.log("Signature is valid, keys are matching"); } else { throw "The signature is invalid. Please make sure the keys match." }

Esto falla para las claves tomadas del servidor, pero cuando generé claves con jsrsasign funciona (aunque necesito hacer que las claves del servidor funcionen).

Ya intenté codificar las claves en HEX en lugar de BASE64, pero eso no ayudó. Dado que soy bastante nuevo en todo el tema de la firma y al final de mis ingenios, cualquier ayuda es muy apreciada.

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Las claves se pueden especificar en diferentes formatos y codificaciones. La clave privada publicada tiene el formato PKCS#8, la clave pública se especifica en formato sin comprimir. Ambos están codificados en Base64.
Con respecto a la importación, una codificación hexadecimal sería más adecuada aquí (como ya se ha hecho, en el código Java/BouncyCastle, o alternativamente en el código JavaScript, por ejemplo aquí ). Entonces la importación con jsrsasign es factible de la siguiente manera:

 // Import as hex encoded PKCS#8 key var privKeyPKCS8Hex = '308193020100301306072a8648ce3d020106082a8648ce3d030107047930770201010420eb1ace196bef4d387911fc610dca34c6aa69c85ad245b15a29429b66eb65ca7ba00a06082a8648ce3d030107a144034200043a12110b6905afdf3eed06025760c1aca70f77362f8bbef998ddfd0c481b6ef3895d0598b76e8cfe395de18a2c8efa6071fa30a0e2cd930c5fa7c34562de54bb'; var privKey = KEYUTIL.getKeyFromPlainPrivatePKCS8Hex(privKeyPKCS8Hex); var signature = new KJUR.crypto.Signature({"alg": "SHA512withECDSA"}); signature.init(privKey); signature.updateString("The quick brown fox jumps over the lazy dog"); var signatureHex = signature.sign(); document.getElementById("signatureHex").innerHTML = signatureHex; var publicKeyUncompressed = '043a12110b6905afdf3eed06025760c1aca70f77362f8bbef998ddfd0c481b6ef3895d0598b76e8cfe395de18a2c8efa6071fa30a0e2cd930c5fa7c34562de54bb'; var pubKey = new KJUR.crypto.ECDSA({'pub': publicKeyUncompressed, 'curve': 'prime256v1'}); var signature = new KJUR.crypto.Signature({"alg": "SHA512withECDSA"}); signature.init(pubKey); signature.updateString("The quick brown fox jumps over the lazy dog"); var verified = signature.verify(signatureHex); document.getElementById("verified").innerHTML = verified;
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jsrsasign/10.4.0/jsrsasign-all-min.js"></script> <p style="font-family:'Courier New', monospace;" id="signatureHex"></p> <p style="font-family:'Courier New', monospace;" id="verified"></p>

También hay otras formas de importar. Por ejemplo, la clave privada podría codificarse con PEM (no se requieren saltos de línea después de cada 64 bytes):

 var privKeyPPCS8PEM = `-----BEGIN PRIVATE KEY----- MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQg6xrOGWvvTTh5EfxhDco0xqppyFrSRbFaKUKbZutlynugCgYIKoZIzj0DAQehRANCAAQ6EhELaQWv3z7tBgJXYMGspw93Ni+LvvmY3f0MSBtu84ldBZi3boz+OV3hiiyO+mBx+jCg4s2TDF+nw0Vi3lS7 -----END PRIVATE KEY-----`; var privKey = KEYUTIL.getKeyFromPlainPrivatePKCS8PEM(privKeyPPCS8PEM);

Para obtener más información sobre las diferentes opciones de importación, consulte la documentación de jsrsasign , por ejemplo,KEYUTIL .

Una nota menor: prime256v1 corresponde a un tamaño de clave (orden del punto base) de 256 bits (32 bytes). Pero con SHA512, está utilizando un resumen que es el doble de grande (64 bytes). En este caso, según NIST FIPS 186-4, se utilizan los n bits más a la izquierda del hash, aquí .

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda