openssl_public_encrypt para Ensemble
Hola.
Necesitamos llamar a un servicio y tenemos que encriptar la petición utilizando una clave pública. Tenemos un ejemplo de cómo realizar la llamada en PHP. También tenemos la clave pública y todos los parámetros que necesitamos. El ejemplo en PHP es éste y funciona (utiliza openssl):
$url = "https://XXXXX/";
$json = '{"api_key":"XXXXX", "id":"1"}';
$jsonEncrypt, = '';
$publicKey = file_get_contents("public.key");
openssl_get_publickey($publicKey);
openssl_public_encrypt($json, $jsonEncrypt, $publicKey);
$jsonEncrypt = base64_encode($jsonEncrypt);
Necesitamos hacer lo mismo en Ensemble. Escribí un post en la comunidad de InterSystems en inglés, y me dijeron que utilizase RSAEncrypt().
He probado esto:
set json = "{""api_key"":""XXXXX"", ""id"":""1""}"
// Abrir el fichero de la clave pública:
set file = ##class(%FileCharacterStream).%New()
set file.Filename = "public.key"
set key = file.Read(file.Size)
// Encriptar el JSON
set jsonEncrypt = $System.Encryption.RSAEncrypt(json, key)
Pero no funciona, me devuelve un string vacío. He buscado por todas partes y no sé por qué no funciona. La clave pública tiene este formato:
-----BEGIN PUBLIC KEY-----
......
......
......
......
-----END PUBLIC KEY-----
Los saltos de línea son LF y está en UTF-8. En qué formato debe estar la clave pública para que funcione en Ensemble? Estoy haciendo algo mal?
Muchas gracias de antemano.
Comments
Perdón, he conseguido obtener el error con RSAGetLastError(), y me devuelve esto:
error:0906D06C:PEM routines:PEM_read_bio:no start line;
Hola Laura, tendría que mirar como usar esa función, pero una cosa que siempre puedes hacer ya que te funciona en openSSL es llamar directamente a OpenSSL. Échale un ojo a este ejemplo https://github.com/drechema/ensemble-smime
Gracias David.
Al final, dado que el comando de terminal funcionaba, esto es exactamente lo que hice, invocar el comando utilizando $ZF(-100, "openssl", ...). Con esto hemos conseguido que funcione. Entiendo que es una solución igualmente válida, no? Me hubiera gustado poder realizarlo con los métodos de clase de $System.Encryption, pero no lo he conseguido.
También le echaría un ojo a este articulo para saber como llamar correctamente al método:
He mirado este artículo y estoy invocando correctamente el método. Lo que sí he tenido que hacer es reconvertir la clave pública de pkcs#8 a pkcs#1 como indica en el artículo. Con eso consigo que encripte, aunque luego el sistema del proveedor me dice que no es válido, pero quizá sea que me falte/sobre algo. Seguiré probando a ver si consigo hacerlo funcionar.
Muchas gracias!