Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

278
Visualizações
Why do my SHA512-ECDSA keys, generated in bouncycastle, mismatch in jsrsasign?

I have an application and a server that both use signed messages (using bouncycastle) to communicate. For a new application, I want to use JS and sign the message using jsrsasign and then verify it on the server side using bouncycastle again. The keys are generated in bouncycastle as well and then transferred to the JS application.

The signature is always invalid for the JS->Server communication, so I tried to sign and verify the message completely in JS and found that this also doesn't work. I am assuming that I am not using the correct configuration, but I fail to figure out the source of the problem.

I am using ECDSA with the prime256v1 curve.

My keys are generated like this:

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))

The generated keys look like this:

privateKey = MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQg6xrOGWvvTTh5EfxhDco0xqppyFrSRbFaKUKbZutlynugCgYIKoZIzj0DAQehRANCAAQ6EhELaQWv3z7tBgJXYMGspw93Ni+LvvmY3f0MSBtu84ldBZi3boz+OV3hiiyO+mBx+jCg4s2TDF+nw0Vi3lS7

publicKey = BDoSEQtpBa/fPu0GAldgwaynD3c2L4u++Zjd/QxIG27ziV0FmLdujP45XeGKLI76YHH6MKDizZMMX6fDRWLeVLs=

For testing I take these keys and run this to see if they are valid on JS side:

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."
}

This fails for the keys taken from server, but when I generated keys with jsrsasign it works (.I need to make the server keys work, though).

I already tried to encode the keys to HEX instead of BASE64, but that didn't help. Since I am fairly new to the whole signing topic and at the end of my wits, any help is deeply appreciated.

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

Keys can be specified in different formats and encodings. The posted private key has the PKCS#8 format, the public key is specified in uncompressed format. Both are Base64 encoded.
With regard to the import, a hex encoding would be more suitable here (as already done, in the Java/BouncyCastle code, or alternatively in the JavaScript code, e.g. here). Then the import with jsrsasign is feasible as follows:

// 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>

There are also other ways of importing. For instance, the private key could be PEM encoded (the line breaks after each 64 bytes are not required):

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

For more information about the different import options, see the documentation of jsrsasign, e.g. KEYUTIL.

One minor note: prime256v1 corresponds to a key size (order of the base point) of 256 bits (32 bytes). But with SHA512, you are using a digest that is twice as large (64 bytes). In this case according to NIST FIPS 186-4 the leftmost n bits of the hash are used, here.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda