Задать вопрос
@HaiZenBerGG

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

сделал тест для него
@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"

в чем может быть проблема? в яве пару дней, так что сильно не бейте коль что
  • Вопрос задан
  • 112 просмотров
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 1
OLEG4120
@OLEG4120
Не надо кодировать подпись в Base64, т.е.
boolean isVerified = KeyPairService.verifyWithPublicKey(data, signature, publicKey);

а сам метод verifyWithPublicKey переделайте, чтобы принимал подпись в виде массива байт
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы