I'm trying to transfer data from a web page to my java spring booth app with integrity guarantee, however, for some reason, I don't want to use a token, instead of a public/private key pair and asynchronous encryption. I have this class in Java for working with signatures
public class KeyPairService {
private final String publicKey;
private final String privateKey;
public KeyPairService() {
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
KeyPair keyPair = keyGen.generateKeyPair();
this.publicKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());
this.privateKey = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("Error generating key pair", e);
}
}
static public boolean verifyWithPublicKey(Object data, String signature, String publicKeyString) {
try {
byte[] decodedPublicKey = Base64.getDecoder().decode(publicKeyString);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedPublicKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
Signature verifySignature = Signature.getInstance("SHA256withRSA");
verifySignature.initVerify(publicKey);
verifySignature.update(KeyPairService.serializeObject(data));
return verifySignature.verify(signature.getBytes());
} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException | InvalidKeySpecException e) {
throw new RuntimeException("Error verifying signature with public key", e);
}
}
public static byte[] serializeObject(Object object) {
try {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
ObjectOutputStream objectStream = new ObjectOutputStream(byteStream);
objectStream.writeObject(object);
objectStream.flush();
return byteStream.toByteArray();
} catch (IOException e) {
throw new RuntimeException("Error serializing object to byte array", e);
}
}
static public byte[] signWithPrivateKey(Object data, String privateKeyString) {
try {
byte[] decodedPrivateKey = Base64.getDecoder().decode(privateKeyString);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedPrivateKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
Signature sign = Signature.getInstance("SHA256withRSA");
sign.initSign(privateKey);
sign.update(serializeObject(data));
return sign.sign();
} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException | InvalidKeySpecException e) {
throw new RuntimeException("Error signing data with private key", e);
}
}
public String getPublicKey() {
return publicKey;
}
public String getPrivateKey() {
return privateKey;
}
}
Help me with the correct object signature on javascript I've written this code
let privateKeyPem = '-----BEGIN PRIVATE KEY-----\n' + privateKey + '\n-----END PRIVATE KEY-----'
console.log(privateKeyPem)
privateKey = forge.pki.privateKeyFromPem(privateKeyPem)
const md = forge.md.sha1.create()
md.update(data, 'utf8')
const hash = md.digest()
const signature = privateKey.sign(md)
//return forge.util.encode64(signature)
console.log(forge.util.encode64(signature))
using the forge library, but it doesn't produce the same signature as the class with the same input object The generated signature in both java and javascript has 344 characters
Thank you in advance
I tried SHA256 - the result is the same, about serialization - similar actions are possible in javascript or in java without it