Подпись RSA Golang не соответствует подписи Java

Я пытаюсь создать подпись RSA, используя стандарт PKCS #1v15. Данные сначала хэшируются с использованием MD5, а алгоритм подписи — SHA256. Но по какой-то причине оба вывода различны, и сервер выдает ошибку для кода Golang. Любой совет будет принят во внимание.

Java-код:

Для контекста:

RSA_ALGORITHM_SIGN = "SHA256WithRSA";

CHARSET = "UTF-8";

private static String getSign(String data, RSAPrivateKey privateKey) {
    try {
        String encodeStr = DigestUtils.md5Hex(data);
        System.out.println(encodeStr);
        Signature signature = Signature.getInstance(RSA_ALGORITHM_SIGN);
        signature.initSign(privateKey);
        signature.update(encodeStr.getBytes(CHARSET));
        byte[] sign = signature.sign();
        System.out.println(sign.length);
        return Base64.encodeBase64URLSafeString(sign);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

Код Голанга:

func GetSignature(data []byte, pk *rsa.PrivateKey) (string, error) {
    m := md5.New()
    _, err := m.Write(data)
    if err != nil {
        return "", err
    }
    encoded := hex.EncodeToString(m.Sum(nil))
    fmt.Println(encoded)
    signature, err := rsa.SignPKCS1v15(rand.Reader, pk, crypto.SHA256, []byte(encoded))
    if err != nil {
        return "", err
    }
    return base64.URLEncoding.EncodeToString(signature), nil
}

Я надеялся, что сервер, который я использую, не выдаст ошибку. Однако, как бы я ни менял код Golang, я получаю ошибки подписи.

Предварительное хеширование с помощью MD5 делает это небезопасным. Шестнадцатеричное кодирование двоичных данных только для того, чтобы затем UTF-8 кодировало их обратно в байты, не имеет никакого смысла. И нет смысла хешировать данные дважды. В Java есть собственный класс Base64 java.util.Base64.

President James K. Polk 07.03.2024 04:53
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
154
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы используете rsa.SignPKCS1v15 (стандарт PKCS #1v15) в своем коде GoLang, но схему SHA256WithRSA в Java. Первый требует явной схемы заполнения, а второй использует неявное дополнение. В вашем коде GoLang вы не выполняете явное заполнение, что приводит к несогласованной генерации подписей между вашими кодами Java и Go. Выполните явное заполнение в коде Golang, как показано ниже:

// Create the PKCS #1v15 padding according to the key size
padding := pkcs1v15Padding(pk.Size(), crypto.MD5)

// Concatenate padding and hashed data
paddedData := append(padding, []byte(encoded)...)

signature, err := rsa.SignPKCS1v15(rand.Reader, pk, crypto.MD5, paddedData)

Привет. Спасибо за комментарий. Как вы и предлагали, я попробовал сделать отступ, однако моя программа выдает ошибку crypto/rsa: input must be hashed message.

Tselmuun 07.03.2024 04:45

попробуйте этот метод, настройте код Go для прямого хэширования данных и подпишите их, не кодируя их в импорт шестнадцатеричной строки ( "crypto" "crypto/md5" "crypto/rand" "crypto/rsa" "encoding/base64" "fmt") func GetSignature(data []byte, pk *rsa.PrivateKey) (string, error) { // Хешируем данные, используя хеш MD5 := md5.Sum(data) // Подписываем хешированные данные, используя подпись SHA256, err := rsa .SignPKCS1v15(rand.Reader, pk, crypto.SHA256, hash[:]) if err != nil { return "", err } return base64.URLEncoding.EncodeToString(signature), nil }

user23500645 07.03.2024 05:10
Ответ принят как подходящий

Итак, я что-то упустил в методе Java.

В Java-коде рабочий процесс — MD5 -> HEX -> SHA256 -> Подпись. В моем более раннем коде Golang я реализовал MD5 -> HEX -> Signature.

Наконец удалось это исправить. Спасибо всем, кто поделился своим коллективным вкладом. Действительно помог мне двигаться в правильном направлении.

Другие вопросы по теме