python google-app-engine openssl cryptography google-cloud-storage

Problemas para verificar un archivo firmado con python



google-app-engine openssl (1)

Finalmente encontré el problema. Estaba tan concentrado en encontrar un problema en el proceso de firma de openssl y no le presté atención al viejo problema de Ctrl + C / Ctrl + V.

Para fines de prueba, copié el ejemplo ''Leer de GCS'' de este tutorial .

Cuando cambié la prueba a la aplicación real, no volví a leer la página y no gcs_file.seek(-1024, os.SEEK_END) .

Como dije en la pregunta original, no soy especialista en Python, pero esta línea solo leía parte del archivo GCS, por lo que la firma era realmente diferente de la original.

Solo corte esa línea de mis métodos de lectura y ahora todo funciona bien.

Intento crear un archivo firmado usando OpenSSL y Python, y no recibo ningún mensaje de error, pero el proceso no funciona correctamente y no puedo encontrar el motivo.

A continuación se muestra mi paso a paso para firmar el archivo y verificar la firma:

  1. Primero creo el crt en línea de comando

    openssl req -nodes -x509 -sha256 -newkey rsa:4096 -keyout "cert.key" -out "cert.crt" -subj "/C=BR/ST=SP/L=SP/O=Company/OU=IT Dept/CN=cert"

En este punto, tengo dos archivos: cert.key y cert.crt

  1. Firme el archivo use un script de Python como a continuación:

    import os.path from Crypto.PublicKey import RSA from Crypto.Signature import PKCS1_v1_5 from Crypto.Hash import SHA256 from base64 import b64encode, b64decode def __init__(self): folder = os.path.dirname(os.path.realpath(__file__)) file_path = os.path.join(folder, ''../static/cert.key'') self.key = open(file_path, "r").read() def sign_data(self, my_file): rsakey = RSA.importKey(self.key) # I opened the cert.key in __init__ signer = PKCS1_v1_5.new(rsakey) digest = SHA256.new() digest.update(my_file) sign = signer.sign(digest) return sign, b64encode(sign)

Todo funciona bien y después de guardar los archivos, tengo otros tres archivos: my_file.csv (el original), my_file.txt.sha256 y my_file.txt.sha256.base64 . En este punto, puedo decodificar el archivo base64 y compararlo con el firmado, y ambos están bien.

El problema es cuando intento verificar la firma con el siguiente comando:

`openssl dgst -sha256 -verify <(openssl x509 -in "cert.crt" -pubkey -noout) -signature my_file.txt.sha256 my_file.csv`

En este punto, siempre recibo el "Error de verificación" y no entiendo por qué.

Tal vez el problema es mi falta de conocimiento de Python, porque cuando firmo el archivo con el siguiente comando (después del paso 1 y antes de usar el script de Python descrito en 2), la misma verificación funciona bien.

openssl dgst -sha256 -sign "cert.key" -out my_file.txt.sha256 my_file.csv

¿Estoy haciendo algo mal?

ACTUALIZAR

En base a los comentarios, probé el script en un virtualv virtual con python 2.7 y funcionó, por lo que el problema debe estar en las operaciones de lectura / escritura.

Estoy actualizando esta consulta con el script completo, incluidas las operaciones de lectura / escritura porque puedo ejecutarlo localmente, pero todavía no aparece ningún error en el entorno de GAE y no puedo entender por qué.

El primer paso es la creación y el almacenamiento de CSV en Google Storage (Bucket) con el siguiente script

import logging import string import cloudstorage as gcs from google.appengine.api import app_identity def create_csv_file(self, filename, cursor=None): filename = ''/'' + self.bucket_name + filename try: write_retry_params = gcs.RetryParams(backoff_factor=1.1) # the cursor stores a MySQL result set if cursor is not None: gcs_file = gcs.open(filename, ''w'', content_type=''text/csv'', retry_params=write_retry_params) for row in cursor: gcs_file.write('',''.join(map(str, row)) + ''/n'') gcs_file.close() except Exception as ex: logging.critical("Problem to write in th GC Storage with the exception:{}".format(ex)) raise ex

Funciona bien y almacena un archivo CSV en la ruta correcta dentro del almacenamiento de Google. Después de esa parte, la siguiente operación de lectura / escritura es la firma del archivo.

def cert_file(self, original_filename): filename = ''/'' + self.bucket_name + original_filename cert = Cert() # This class just has one method, that is that described in my original question and is used to sign the file. with gcs.open(filename) as cloudstorage_file: cloudstorage_file.seek(-1024, os.SEEK_END) signed_file, encoded_signed_file = cert.sign_data(cloudstorage_file.read()) #the method to sign the file signature_content = encoded_signed_file signed_file_name = string.replace(original_filename, ''.csv'', ''.txt.sha256'') encoded_signed_file_name = string.replace(signed_file_name, ''.txt.sha256'', ''.txt.sha256.base64'') self.inner_upload_file(signed_file, signed_file_name) self.inner_upload_file(encoded_signed_file, encoded_signed_file_name) return signed_file_name, encoded_signed_file_name, signature_content

inner_upload_file , solo guarde los nuevos archivos en el mismo contenedor:

def inner_upload_file(self, file_data, filename): filename = ''/'' + self.bucket_name + filename try: write_retry_params = gcs.RetryParams(backoff_factor=1.1) gcs_file = gcs.open(filename, ''w'', content_type=''application/octet-stream'', retry_params=write_retry_params) gcs_file.write(file_data) gcs_file.close() except Exception as ex: logging.critical("Problem to write in th GC Storage with the exception:{}".format(ex)) raise ex

Aquí está la aplicación.yaml para referencia. El cert.key y el cert.crt generados por la línea de comando se almacenan en una carpeta estática dentro de la carpeta de la aplicación (el mismo directorio donde está mi app.yaml).

ACTUALIZACIÓN 2

Después de los comentarios, intenté ejecutar el proceso de firma localmente y luego comparar los archivos. A continuación se muestra el paso por setp y los resultados.

Primero, python sign.py file_name el proceso de firma para ejecutar como python sign.py file_name .

#!/usr/bin/python import sys import os from Crypto.PublicKey import RSA from Crypto.Signature import PKCS1_v1_5 from Crypto.Hash import SHA256 from base64 import b64encode, b64decode file_path = ''static/cert.key'' key = open(file_path, "rb").read() rsakey = RSA.importKey(key) signer = PKCS1_v1_5.new(rsakey) digest = SHA256.new() file_object = open(sys.argv[1], "r") digest.update(file_object.read()) sign = signer.sign(digest) signed_path = "signed" f = open(signed_path + ''.txt.sha256'', ''w'') f.write(sign) f.close() f2 = open(signed_path + ''.txt.sha256.base64'', ''w'') f2.write(b64encode(sign)) f2.close()

Ejecuté el proceso automático que guardaba el archivo firmado en el cubo de GCS (junto con el archivo CSV original). Después de esto, descargo ambos archivos a través del panel web de Google para GCS.

python sign.py gcs_file_original.csv el comando python sign.py gcs_file_original.csv en un virtualenv con python 2.7.10 utilizando el archivo CSV que acabo de descargar.

Después de eso, cmp -b gcs_signed.txt.sha256 locally_signed.txt.sha256 los dos archivos firmados con cmp -b gcs_signed.txt.sha256 locally_signed.txt.sha256 da cmp -b gcs_signed.txt.sha256 locally_signed.txt.sha256 resultado:

gcs_signed.txt.sha256 locally_signed.txt.sha256 different: byte 1, line 1 is 24 ^ T 164 t

Usando VisualBinaryDiff , el resultado parece dos archivos totalmente diferentes.

Ahora, sé el problema, pero no tengo idea de cómo solucionarlo. Este problema está siendo muy divertido.