Я пытаюсь создать подпись 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, я получаю ошибки подписи.




Вы используете 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.
попробуйте этот метод, настройте код 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 }
Итак, я что-то упустил в методе Java.
В Java-коде рабочий процесс — MD5 -> HEX -> SHA256 -> Подпись. В моем более раннем коде Golang я реализовал MD5 -> HEX -> Signature.
Наконец удалось это исправить. Спасибо всем, кто поделился своим коллективным вкладом. Действительно помог мне двигаться в правильном направлении.
Предварительное хеширование с помощью MD5 делает это небезопасным. Шестнадцатеричное кодирование двоичных данных только для того, чтобы затем UTF-8 кодировало их обратно в байты, не имеет никакого смысла. И нет смысла хешировать данные дважды. В Java есть собственный класс Base64
java.util.Base64.