RSA подпись в java spring boot. где ошибка?
привет всем!
накатал вот такой класс
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(String 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(data.getBytes()); return verifySignature.verify(signature.getBytes()); } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException | InvalidKeySpecException e) { throw new RuntimeException("Error verifying signature with public key", e); } } static public byte[] signWithPrivateKey(String 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(data.getBytes()); 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; } } |
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(String 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(data.getBytes()); return verifySignature.verify(signature.getBytes()); } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException | InvalidKeySpecException e) { throw new RuntimeException("Error verifying signature with public key", e); } } static public byte[] signWithPrivateKey(String 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(data.getBytes()); 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; } }
сделал тест для него
@SpringBootTest public class KeyPairServiceTest { @Test public void testSignAndVerifyJson() { String jsonString = "Руддщ"; // Получаем открытый и закрытый ключи из сервиса KeyPairService KeyPairService keyPairService = new KeyPairService(); String publicKey = keyPairService.getPublicKey(); String privateKey = keyPairService.getPrivateKey(); // Преобразуем JSON-строку в URL-кодированные данные String data = jsonString; // Подписываем данные с помощью закрытого ключа byte[] signature = KeyPairService.signWithPrivateKey(data, privateKey); // Проверяем подпись с помощью открытого ключа boolean isVerified = KeyPairService.verifyWithPublicKey(data, Base64.getEncoder().encodeToString(signature), publicKey); // Проверяем, успешна ли верификация assertTrue(isVerified, "Signature verification failed"); } } |
@SpringBootTest public class KeyPairServiceTest { @Test public void testSignAndVerifyJson() { String jsonString = "Руддщ"; // Получаем открытый и закрытый ключи из сервиса KeyPairService KeyPairService keyPairService = new KeyPairService(); String publicKey = keyPairService.getPublicKey(); String privateKey = keyPairService.getPrivateKey(); // Преобразуем JSON-строку в URL-кодированные данные String data = jsonString; // Подписываем данные с помощью закрытого ключа byte[] signature = KeyPairService.signWithPrivateKey(data, privateKey); // Проверяем подпись с помощью открытого ключа boolean isVerified = KeyPairService.verifyWithPublicKey(data, Base64.getEncoder().encodeToString(signature), publicKey); // Проверяем, успешна ли верификация assertTrue(isVerified, "Signature verification failed"); } }
но он фейлится с ошибкой "подпись длиной 344, а ожидается 256"
в чем может быть проблема? в яве пару дней, так что сильно не бейте коль что
Дополнительно:
Ответы:
Не надо кодировать подпись в Base64, т.е.
boolean isVerified = KeyPairService.verifyWithPublicKey(data, signature, publicKey); |
boolean isVerified = KeyPairService.verifyWithPublicKey(data, signature, publicKey);
а сам метод verifyWithPublicKey переделайте, чтобы принимал подпись в виде массива байт
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для создания RSA подписи в Java Spring Boot есть несколько шагов, которые нужно выполнить. Возможно, ошибка может быть связана с неправильной реализацией одного из этих шагов. Давайте разберемся подробнее.
1. Генерация ключей RSA:
Для начала нам нужно сгенерировать открытый и закрытый ключи RSA. Можно воспользоваться библиотекой `java.security` для этого. Вот пример кода:
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(2048); KeyPair keyPair = keyPairGenerator.generateKeyPair(); PublicKey publicKey = keyPair.getPublic(); PrivateKey privateKey = keyPair.getPrivate();
2. Создание подписи:
Далее нам нужно создать подпись с использованием закрытого ключа. Мы можем воспользоваться классом `Signature` для этого. Вот пример кода:
Signature privateSignature = Signature.getInstance("SHA256withRSA"); privateSignature.initSign(privateKey); privateSignature.update(data); byte[] signature = privateSignature.sign();
3. Проверка подписи:
Наконец, чтобы проверить подпись, нам нужно использовать открытый ключ. Вот пример кода:
Signature publicSignature = Signature.getInstance("SHA256withRSA"); publicSignature.initVerify(publicKey); publicSignature.update(data); boolean isSignatureValid = publicSignature.verify(signature);
Убедитесь, что в вашем коде правильно передается данные для подписи и проверки, а также проверьте, что ключи корректно сгенерированы и используются. Если после проверки кода проблема остается, пожалуйста, уточните, в каком именно месте возникает ошибка, чтобы мы могли помочь вам более точно.