# Ejemplos firma digital

# OpenSSL

rm -f base.txt signature.bin signature.txt &&\
echo -n "<CONSUMER_ID>\n<TIMESTAMP>\n<VERSION>\n" > base.txt &&\
openssl dgst -sha256 -sign ./private_key.pem -out ./signature.bin ./base.txt &&\
openssl base64 -in signature.bin -out signature.txt &&\
echo $(tr -d '\n' < signature.txt)

# C#

# IRSAEncryptionManager.cs

namespace zuul.Gateway.Client.Crypto
{ public interface IRsaEncryptionManager { string RsaEncrypt(string plainText); }
}

# IApp2AppHeaderFormatter.cs

using System.Collections.Generic; namespace zuul.Gateway.Client.Crypto
{ public interface IApp2AppHeaderFormatter { IDictionary<string, string> FormApp2AppHeaders(); }
}

# App2AppHeaderFormatter.cs

using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using Serilog; namespace zuul.Gateway.Client.Crypto
{ public class App2AppHeaderFormatter : IApp2AppHeaderFormatter { private const string AuthSignatureHeader = "WM_SEC.AUTH_SIGNATURE"; private const string ConsumerIdHeader = "WM_CONSUMER.ID"; private const string CorrelationHeader = "WM_QOS.CORRELATION_ID"; private const string KeyVersionHeader = "WM_SEC.KEY_VERSION"; private const string TimestampHeader = "WM_CONSUMER.INTIMESTAMP"; private const string CorrelationHeaderValue = "request-id-1"; private readonly IRsaEncryptionManager _encryptionManager; private readonly ILogger _logger; private readonly string _consumerId; private readonly string _keyVersion; public App2AppHeaderFormatter(string keyVersion, string consumerId, IRsaEncryptionManager encryptionManager, ILogger logger) { _keyVersion = keyVersion; _consumerId = consumerId; _encryptionManager = encryptionManager; _logger = logger; } public IDictionary<string, string> FormApp2AppHeaders() { var headerDict = new Dictionary<string, string>(); var unixTimeMs = DateTimeOffset.Now.ToUnixTimeMilliseconds().ToString(); var integrityString = this.FormIntegrityString(unixTimeMs); headerDict[AuthSignatureHeader] = this.SignMessage(integrityString); headerDict[ConsumerIdHeader] = _consumerId; headerDict[CorrelationHeader] = CorrelationHeaderValue; headerDict[KeyVersionHeader] = _keyVersion; headerDict[TimestampHeader] = unixTimeMs; return headerDict; } private string FormIntegrityString(string timestamp) { return this._consumerId + "\n" + timestamp + "\n" + this._keyVersion + "\n"; } private string SignMessage(string integrityString) { var signature = string.Empty; try { signature = this._encryptionManager.RsaEncrypt(integrityString); } catch (CryptographicException exp) { this._logger.Error("[App2AppFormatter] Failed to sign message to config service.", exp); } return signature; } }
}

# RSAEncryptionManager.cs

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security; namespace zuul.Gateway.Client.Crypto
{ public class RsaEncryptionManager : IRsaEncryptionManager { private readonly RSAParameters _rsaParameters; public RsaEncryptionManager(string privateKeyPem) { PemReader pr = new PemReader(new StringReader(privateKeyPem)); RsaPrivateCrtKeyParameters privateKey = (RsaPrivateCrtKeyParameters)pr.ReadObject(); _rsaParameters = DotNetUtilities.ToRSAParameters(privateKey); } public string RsaEncrypt(string plainText) { var byteConverter = new UTF8Encoding(); var plainTextBytes = byteConverter.GetBytes(plainText); using (var csp = new RSACryptoServiceProvider()) { csp.ImportParameters(this._rsaParameters); var encryptedData = csp.SignData(plainTextBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); return Convert.ToBase64String(encryptedData); } } }
}

# JAVA

# SignatureGenerator.java

import java.io.ObjectStreamException;
import java.security.KeyRep;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet; public class SignatureGenerator { public static void main(String[] args) { SignatureGenerator generator = new SignatureGenerator(); String consumerId = "00000x0x-000x-0x00-xx00-x0x000xx00xx" String privateKeyVersion = "1"; String privateKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; long inTimestamp = System.currentTimeMillis(); Map<String, String> map = new HashMap<>(); map.put("WM_CONSUMER.ID", consumerId); map.put("WM_CONSUMER.INTIMESTAMP", Long.toString(inTimestamp)); map.put("WM_SEC.KEY_VERSION", privateKeyVersion); String[] array = canonicalize(map); String data = null; try { data = generator.generateSignature(privateKey, array[1]); } catch(Exception e) { } System.out.println("inTimestamp: " + inTimestamp); System.out.println("Signature: " + data); } public String generateSignature(String key, String stringToSign) throws Exception { Signature signatureInstance = Signature.getInstance("SHA256WithRSA"); ServiceKeyRep keyRep = new ServiceKeyRep(KeyRep.Type.PRIVATE, "RSA", "PKCS#8", Base64.getDecoder().decode(key)); PrivateKey resolvedPrivateKey = (PrivateKey) keyRep.readResolve(); signatureInstance.initSign(resolvedPrivateKey); byte[] bytesToSign = stringToSign.getBytes("UTF-8"); signatureInstance.update(bytesToSign); byte[] signatureBytes = signatureInstance.sign(); String signatureString = Base64.getEncoder().encodeToString(signatureBytes); return signatureString; } protected static String[] canonicalize(Map<String, String> headersToSign) { StringBuffer canonicalizedStrBuffer=new StringBuffer(); StringBuffer parameterNamesBuffer=new StringBuffer(); Set<String> keySet=headersToSign.keySet(); // Create sorted key set to enforce order on the key names SortedSet<String> sortedKeySet=new TreeSet<String>(keySet); for (String key :sortedKeySet) { Object val=headersToSign.get(key); parameterNamesBuffer.append(key.trim()).append(";"); canonicalizedStrBuffer.append(val.toString().trim()).append("\n"); } return new String[] {parameterNamesBuffer.toString(), canonicalizedStrBuffer.toString()}; } class ServiceKeyRep extends KeyRep	{ private static final long serialVersionUID = -7213340660431987616L; public ServiceKeyRep(Type type, String algorithm, String format, byte[] encoded) { super(type, algorithm, format, encoded); } protected Object readResolve() throws ObjectStreamException { return super.readResolve(); } } }

# JavaScript

# index.js

const express = require('express')
const crypto = require('crypto')
const fs = require('fs') const app = express()
const cert = fs.readFileSync('private_key.pem') const generateSignature = (verifiableData, privateKey) => { const rsaSigner = crypto.createSign("RSA-SHA256"); rsaSigner.update(verifiableData); return rsaSigner.sign(privateKey, "base64");
} app.use(express.json()) app.get('/', (req, res) => { res.send('Hello World!')
}) app.post('/sign', (req, res) => { const { CONSUMER_ID, TIMESTAMP, KEY_VERSION } = req.body; const dataToSign = ''+CONSUMER_ID+'\n'+TIMESTAMP+'\n'+KEY_VERSION+'\n'; console.log("dataToSign-", dataToSign) const signed = generateSignature(dataToSign, cert) console.log("signed -",signed) res.send(signed)
}) app.listen(3000, () => console.log('rs256 server listening...'))

# Python

# sign.py

#!/usr/bin/env python import sys, time def printError(msg=''): if msg != "": print("Error: " + msg) print('Usage: ') print(sys.argv[0] + " [private key file] [consumer ID] [Key version]") print('') print('Example: ') print(sys.argv[0] + " private_key.pem 44444444-23f9-3333-2222-111111111111 1") print('') print('') sys.exit() def sign_data(private_key, data): from Crypto.PublicKey import RSA from Crypto.Signature import PKCS1_v1_5 from Crypto.Hash import SHA256 from base64 import b64encode, b64decode key = open(private_key, "r").read() rsakey = RSA.importKey(key) signer = PKCS1_v1_5.new(rsakey) digest = SHA256.new() digest.update(data.encode('utf-8')) sign = signer.sign(digest) return b64encode(sign) def main(argv): global logData global hostname try: privateKey = str(sys.argv[1]) consumedId = str(sys.argv[2]) keyVersion = str(sys.argv[3]) except: printError() epoch_time = int(time.time()) * 1000 data = consumedId + '\n' + str(epoch_time) + '\n' + keyVersion + '\n' print('Timestamp:', epoch_time) print('Signature:' , sign_data(privateKey, data).decode()) if __name__ == "__main__": main(sys.argv)

# Golang

# signature.go

package main
import ( "crypto" "crypto/rand" "crypto/rsa" "crypto/sha256" "crypto/x509" "encoding/base64" "encoding/pem" "errors" "fmt" "strconv" "time" "strings"
)
var ( ConsumerId string = "Your consumer ID" Token string = "your private key string" privateKeyPrefix string = "-----BEGIN PRIVATE KEY-----" privateKeySuffix string = "-----END PRIVATE KEY-----"
)
func main(){ privateKey := []byte("your private key string") consumerId := "Your consumer ID" timestamp,signature,err := Sign(formatPrivateKey(privateKey), consumerId, strconv.Itoa(1)) //Sign(privateKey,consumerId,"1.0.0") fmt.Println(timestamp) fmt.Println(signature) if err != nil { fmt.Print(err.Error()) } }
func Sign(privateKey []byte, consumerId string, version string) (string, string, error) { fmt.Println(privateKey) block, _ := pem.Decode(privateKey) if block == nil { return "", "", errors.New("ssh: no private key found") } var pKey *rsa.PrivateKey switch block.Type { case "PRIVATE KEY": parseResult, err := x509.ParsePKCS8PrivateKey(block.Bytes) if err != nil { return "", "", err } pKey = parseResult.(*rsa.PrivateKey) default: return "", "", fmt.Errorf("ssh: unsupported private key type %q", block.Type) } timestamp := strconv.FormatInt(time.Now().UnixNano()/int64(time.Millisecond), 10) toSign := fmt.Sprintf("%v\n%v\n%v\n", consumerId, timestamp, version) h := sha256.New() h.Write([]byte(toSign)) d := h.Sum(nil) signed, err := rsa.SignPKCS1v15(rand.Reader, pKey, crypto.SHA256, d) if err != nil { fmt.Println("erroring oit") // log.Error("could not sign, error: %v", err) } signature := base64.StdEncoding.EncodeToString(signed) //log.Debug("WM_CONSUMER.ID: %v\nWM_CONSUMER.INTIMESTAMP: %v\nWM_SEC.KEY_VERSION: %v\nWM_SEC.AUTH_SIGNATURE: %v\n", consumerId, timestamp, version, signature) fmt.Println(timestamp) fmt.Println(signature) return signature, timestamp, err
} func formatPrivateKey(privateKey []byte) []byte { if strings.HasPrefix(string(privateKey), privateKeyPrefix) { return privateKey } else { result := []byte(privateKeyPrefix) result = append(result, '\n') result = append(result, privateKey...) result = append(result, '\n') result = append(result, []byte(privateKeySuffix)...) return result }
}