RSA подпись в java spring boot. где ошибка?

Ссылка скопирована
1 ответ

привет всем!
накатал вот такой класс

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 переделайте, чтобы принимал подпись в виде массива байт

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Дмитрий К. Ответ

Для создания 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();

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

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

Signature publicSignature = Signature.getInstance("SHA256withRSA"); publicSignature.initVerify(publicKey); publicSignature.update(data); boolean isSignatureValid = publicSignature.verify(signature);

Убедитесь, что в вашем коде правильно передается данные для подписи и проверки, а также проверьте, что ключи корректно сгенерированы и используются. Если после проверки кода проблема остается, пожалуйста, уточните, в каком именно месте возникает ошибка, чтобы мы могли помочь вам более точно.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно