Шифрование строки подписи на Python – Ошибка: Невозможно десериализовать основные данные.

Вопрос или проблема

У меня есть следующий код на Python:

import base64
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization

private_key_pem = """
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDCpA0jK8IgLtV+
b/X3t+cmt9r3owRyD
Ywbm6Kbsvj/pXNYaI47toIk=
-----END PRIVATE KEY-----
"""

data = b"""GET
/v1/contas/aa/aa
agencia=3995&conta=75557

eyJhbGciOiJSUzUxMiJ9.ew0KIsDQoiYXVkIjogImh0dHBzOi8vb3BlbmFwaS1heHdheS5hcGkuc
1728392567000
2024-10-08T10:02:00-00:00
SHA256"""

private_key = serialization.load_pem_private_key(
    private_key_pem.encode('utf-8'),
    password=None, 
    backend=default_backend()
)

signature = private_key.sign(
    data,
    padding.PKCS1v15(),
    hashes.SHA256()
)

signature_b64 = base64.b64encode(signature).decode('utf-8')

signature_b64 = signature_b64.rstrip('=\n').replace('+', '-').replace("https://stackoverflow.com/", '_')
print(signature_b64)

    

Эта функция выше создает подпись с использованием закрытого ключа и работает без проблем на Python. Но мне нужно передать эту функцию в базу данных PostgreSQL, используя plpython3u, поэтому я replicated это следующим образом:

DROP FUNCTION IF EXISTS public.teste;
CREATE OR REPLACE FUNCTION public.teste()
RETURNS TEXT AS $$
import base64
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization

private_key_pem = '''-----BEGIN PRIVATE KEY-----
mt9r3owRyDOej0p9qDP0kO0v3eQsKSKmMnV1/WDo0r6Wo/cjsMs4mFC9O
nqvy26/1xE1+mHBoC/+rvhoEn59kzL
Ywbm6Kbsvj/pXNYaI47toIk=
-----END PRIVATE KEY-----'''

data = """GET
/v1/contas/aa/aa
agencia=aa&conta=aa

eyJhbGciOiJSUzUxMiJ9.ew0KInZlciI6ICIxLjAiLA0KImlzcyI6Ih5LmFwaS5wcmViYW5jby5jb20uYnIvYXV0aC9zZXJ2ZXIvdjEuMS90b2tlbiIsDQKGn2JWQ
1728392567000
2024-10-08T10:02:00-00:00
SHA256"""

private_key = serialization.load_pem_private_key(
    private_key_pem.encode('utf-8'),
    password=None, 
    backend=default_backend()
)

signature = private_key.sign(
    data,
    padding.PKCS1v15(),
    hashes.SHA256()
)

signature_b64 = base64.b64encode(signature).decode('utf-8')

signature_b64 = signature_b64.rstrip('=\n').replace('+', '-').replace("https://stackoverflow.com/", '_')
plpy.notice(signature_b64)
$$ LANGUAGE plpython3u;

Функции абсолютно одинаковы, но при выполнении функции в базе данных я получаю ошибку:

Ошибка SQL [38000]: ERROR: ValueError: (‘Не удалось десериализовать данные ключа. Данные могут быть в неправильном формате, предоставленный пароль может быть неверным, он может быть зашифрован с использованием неподдерживаемого алгоритма или может быть неподдерживаемым типом ключа (например, кривые EC с явными параметрами).’, [<OpenSSLError(code=503841036, lib=60, reason=524556, reason_text=unsupported)>])
Где: Traceback (самый последний вызов):
PL/Python функция “teste”, строка 44, в
private_key = serialization.load_pem_private_key(
PL/Python функция “teste”

Я не понимаю, почему возникает ошибка, поскольку данные и функции абсолютно идентичны.

Ответ или решение

Проблема, с которой вы столкнулись, связана с форматом закрытого ключа, который вы используете в вашей функции PL/Python в PostgreSQL. Ошибка, которую вы получили, указывает на то, что библиотека cryptography не может десериализовать данные ключа, вероятно из-за неверного формата.

Ошибка десериализации ключа

Ваша ошибка может быть вызвана несколькими причинами:

  1. Неверный формат ключа: Убедитесь, что закрытый ключ правильно отформатирован и соответствует требуемому стандарту. Например, если вы используете ключ в формате PKCS#8, он должен начинаться с -----BEGIN PRIVATE KEY-----, а если в формате PKCS#1 — -----BEGIN RSA PRIVATE KEY-----.

  2. Пробелы и переводы строк: Проверьте, нет ли лишних пробелов, символов перевода строки или ошибок при копировании ключа. Даже небольшие изменения могут вызвать проблемы при десериализации.

  3. Совместимость с библиотекой: Убедитесь, что версия библиотеки cryptography, используемая в среде PostgreSQL, поддерживает формат вашего ключа.

Решение проблемы

Вот что вы можете сделать для решения вашей проблемы:

  1. Замените закрытый ключ: Попробуйте использовать другой закрытый ключ. Убедитесь, что он корректен и соответствует формату, который может обрабатывать библиотека cryptography.

  2. Проверьте библиотеку: Убедитесь, что вы используете совместимую версию библиотеки cryptography в вашей среде PostgreSQL. Версия библиотеки в PostgreSQL может отличаться от той, что установлена в вашем локальном Python.

  3. Проверьте код: Убедитесь, что код не имеет лишних символов и корректно отформатирован. Иногда проблемы могут возникнуть из-за ошибок в коде, даже если они неочевидны при первом взгляде.

Вот пример, как можно передавать закрытый ключ и данные в вашем коде:

private_key_pem = """
-----BEGIN PRIVATE KEY-----
...ваш ключ...
-----END PRIVATE KEY-----
"""

data = b"""GET
/v1/contas/aa/aa
agencia=3995&amp;conta=75557

eyJhbGciOiJSUzUxMiJ9....
...
SHA256"""

Обратите внимание на то, что переменная data должна быть типом bytes (в вашем случае это строка, которая будет преобразована в байты).

Заключение

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

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

Используя эти рекомендации, вы сможете устранить проблему с десериализацией ключа.

Оцените материал
Добавить комментарий

Капча загружается...