Signature elementas

Elemento signature reikšmė užtikrina užklausos duomenų teisingumą. Iš pasirašomų elementų sekos sudaroma tekstinė pasirašomos informacijos reprezentacija. Ši reprezentacija sudaroma eilės tvarka apjungiant visų užklausos XML elementų tekstines reprezentacijas. Jei elementas yra praleistas web serviso užklausoje, jis taip pat yra praleidžiamas generuojant parašo reikšmę. Kiekvienas nepraleistas elementas reprezentuojamas tokiu formatu: „reikšmė” (čia „pavadinimas” yra elemento pavadinimas užklausos ar atsakymo XML struktūroje, „reikšmė” yra to elemento reikšmė). Kiekvieno elemento reikšmė generuojama pagal elemento tipą naudojantis tokiomis taisyklėmis:

  • boolean tipo elemento reikšmė verčiama į tekstinę vertę „true” arba „false”;
  • kompleksiniai tipai (angl. complex type) formuojami be pradžios ir užveriančiosios elemento pavadinimo gairių (angl. tags);
  • tekstinė pasirašomos informacijos reprezentacija (signature elementas) konvertuojama į baitų seką naudojant UTF-8 koduotę;
  • elementų eiliškumas pagal onesign ir multisign instrukcijoje pateiktus elementų aprašymus;
  • baitų seka pasirašoma kliento sistemoje kliento privačiu raktu. Pasirašymui naudojamas SHA1 ir RSA algoritmai;
  • pasirašomo arba pasirašomų dokumento baitai (content elementas) nėra naudojami parašui skaičiuoti (failo turinys nėra įtraukiamas į parašą - signature elementas).

PHP pavyzdys

Sugeneruojame privatų ir viešą raktą sau patogiu būdu.

turime privatų RSA raktą:

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,42BC45A9B8B8B912

hAUGg985zGxjzZZFT12n+YTesn/mydDaobeI+NW/t/j5xWLMB3R53BgfL4PcUonk
S48oTgsIMovyi3UHsWYSjd2IelD9p6yi13dhEiSiA+3z8tJ5D4mEmDuRJtujab0S
DgL5pszaceR0i0WBMRY0DF6rHiAwWe7MCPKpLyZJPEtDJIgpsIHhihS8wUSHOLqz
Lybc3pHxTmp8+WthfcKnR5TKtu/Gw5cHriM8Ch0cYskZPa8zSTF3Mn74kJgFqrQO
7p33z9yQMKNKtan/XdrxilsxloiRCYG5C90R7OOT5ALvFQGQgty8h5wXkTD5FuCl
ZR2FqQmXLx3un9h5X28IYPBe745uE2sHYsFgb3bESUHrhRHiwj9xiwQXAz6ZTOe0
dtcVIuxQlpTPXSQrjsDXiConKEcWxDbQ4kVYG0L3ITMdzE5rvfJNMuQgH+8ssygB
VkLhWtI/oVtVOT0eONorEZuEtkbYU+LSDAi/eYjjAjRFV9gRtBo+xI8KPdtkaOJj
mvbKLgBVwjUXy35CvaovVOPom+qHvKFKWdFTSHX0j2HbL/un72Nd6a5qzZaSf9dN
9n+DyxVVRhldHtxjm82+FnUovB3n2ljJF2qjt/X/36dZ68/FI2rNUOXODlU3hdf4
Z93JhrSq6nLVVQLplyZSXdyvg0gKd+51CcplVYuvaGF0axfffYgSsqgjK0PnA+8U
r/3+53Y9ThPkfcVcUaRLuQh2KO+serCJsdeHwTzEjs1LcmfARmZ3HaGiLCDwuhyg
eVbR/Pm9i2Jj4hLUhtIDn4StIOiTW9AIATXGStx+KEM=
-----END RSA PRIVATE KEY-----

turime viešą RSA raktą, kurį perduodame GoSign.lt administratoriams:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCZTsMmpwWuWRLTCJblBziSElIp
u0DrwNkLu9aY11qtlIGsR0XLuOTKq2m89f8K9mMqf/i9XAmTmKz/Xx6aqAXUPuxL
1bwI7W08yfmxmwn9K0YB9pdayr39KKsjbX8WxZrAvUQkrQ5+be41MOfelA7K6IxI
qcl2HbJLeoYAWOZpLQIDAQAB
-----END PUBLIC KEY-----

programinėmis priemonėmis sugeneruojame masyvą (Multisign):

[
    'clientInfo' =>
    [
        'clientId' => 'client_id',
        'signerPersonalCode' => 'personal_code',
        'responseUrl' => 'http://example.com/app',
    ],
    'signingType' => 'Signature',
    'files' => 
    [
        [0] => 
        [
            'fileDigest' => '4paS4paSTXLilpLilpJLbc27MeKWkkvilpJeVzkw4paS',
            'fileName' => 'pdf.pdf',
            'fileId' => '111111',
            'fileURL' => 'https://example.com/pdf.pdf',
        ],
    ],
]

serializuojame masyvą, kurį ir pasirašysime:

<clientId>client_id</clientId><signerPersonalCode>signer_code</signerPersonalCode><responseUrl>http://example.com/app</responseUrl><signingType>Signature</signingType><fileDigest>0v5NcpPFHEttzbsxm0urXlc5MIE=</fileDigest><fileName>pdf.pdf</fileName><fileId>111111</fileId><fileURL>https://example.com/pdf.pdf</fileURL>

programinėmis priemonėmis sugeneruojame masyvą (OneSign):

[
    'clientInfo' =>
    [
        'clientId' => 'client_id',
        'signerPersonalCode' => 'personal_code',
        'responseUrl' => 'http://example.com/app',
    ],
    'signingType' => 'Signature',
    'file' => [
        'fileDigest' => '4paS4paSTXLilpLilpJLbc27MeKWkkvilpJeVzkw4paS',
        'fileName' => 'pdf.pdf',
        'content' => 'failo_turinys_base64',
     ],
]

serializuojame masyvą, kurį ir pasirašysime:

<clientId>client_id</clientId><signerPersonalCode>signer_code</signerPersonalCode><responseUrl>http://example.com/app</responseUrl><signingType>Signature</signingType><fileDigest>0v5NcpPFHEttzbsxm0urXlc5MIE=</fileDigest><fileName>pdf.pdf</fileName>

atkreipkite dėmesį:

  • rezultate nėra įtraukiami kompleksinio tipo elementai kaip: clientInfo, files ir t.t..;
  • kadangi saugumui užtikrinti užtenka fileDigest rezultate nėra įtraukiamas file content elementas.

pasirašome naudojant PHP:

function sign(string $content, string $privateKey)
{
	$sign = '';
		
	$key = openssl_get_privatekey($privateKey);
		
	openssl_sign($content, $sign, $key);
		
	return $sign;
}

$privateKey = '-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,42BC45A9B8B8B912

hAUGg985zGxjzZZFT12n+YTesn/mydDaobeI+NW/t/j5xWLMB3R53BgfL4PcUonk
S48oTgsIMovyi3UHsWYSjd2IelD9p6yi13dhEiSiA+3z8tJ5D4mEmDuRJtujab0S
DgL5pszaceR0i0WBMRY0DF6rHiAwWe7MCPKpLyZJPEtDJIgpsIHhihS8wUSHOLqz
Lybc3pHxTmp8+WthfcKnR5TKtu/Gw5cHriM8Ch0cYskZPa8zSTF3Mn74kJgFqrQO
7p33z9yQMKNKtan/XdrxilsxloiRCYG5C90R7OOT5ALvFQGQgty8h5wXkTD5FuCl
ZR2FqQmXLx3un9h5X28IYPBe745uE2sHYsFgb3bESUHrhRHiwj9xiwQXAz6ZTOe0
dtcVIuxQlpTPXSQrjsDXiConKEcWxDbQ4kVYG0L3ITMdzE5rvfJNMuQgH+8ssygB
VkLhWtI/oVtVOT0eONorEZuEtkbYU+LSDAi/eYjjAjRFV9gRtBo+xI8KPdtkaOJj
mvbKLgBVwjUXy35CvaovVOPom+qHvKFKWdFTSHX0j2HbL/un72Nd6a5qzZaSf9dN
9n+DyxVVRhldHtxjm82+FnUovB3n2ljJF2qjt/X/36dZ68/FI2rNUOXODlU3hdf4
Z93JhrSq6nLVVQLplyZSXdyvg0gKd+51CcplVYuvaGF0axfffYgSsqgjK0PnA+8U
r/3+53Y9ThPkfcVcUaRLuQh2KO+serCJsdeHwTzEjs1LcmfARmZ3HaGiLCDwuhyg
eVbR/Pm9i2Jj4hLUhtIDn4StIOiTW9AIATXGStx+KEM=
-----END RSA PRIVATE KEY-----';

$content = '<clientId>client_id</clientId><signerPersonalCode>signer_code</signerPersonalCode><responseUrl>http://example.com/app</responseUrl><signingType>Signature</signingType><fileDigest>0v5NcpPFHEttzbsxm0urXlc5MIE=</fileDigest><fileName>pdf.pdf</fileName><fileId>111111</fileId><fileURL>https://example.com/pdf.pdf</fileURL>';

$signature = sign($content, $privateKey);

echo $signature;

echo base64_encode($signature);

gauname:

6Lտ▒M▒▒$a▒▒~▒▒▒▒▒X▒ơ▒⫧▒▒▒땱p8▒▒[▒▒F!3▒iK▒▒▒▒▒7~
                                                            G▒O▒|▒u▒Ё▒T|t+*▒▒+▒▒▒▒▒;▒E▒4H▒x▒▒~▒▒▒▒▒~1▒1▒T"▒▒mv▒j▒E
NkzVv5BN4o8apCRhi6J+kJXXBOfMWJDGocniq6eM4errlbFwOOrsW67iRh0hM6scaQ5Lzuf35/c3fgtHHeNPqXzHdQTRDtCBBfNUfHQrKt3gK6UEzfChBtfeO9tFiR80SJJ4trt+kcP197kR+6y8fjHCMcJUIt/NbXaFahf5qkU=

base64 encode reikšmė perduodama per signature užklausos elementą:

<signature>NkzVv5BN4o8apCRhi6J+kJXXBOfMWJDGocniq6eM4errlbFwOOrsW67iRh0hM6scaQ5Lzuf35/c3fgtHHeNPqXzHdQTRDtCBBfNUfHQrKt3gK6UEzfChBtfeO9tFiR80SJJ4trt+kcP197kR+6y8fjHCMcJUIt/NbXaFahf5qkU=</signature>

JAVA pavyzdys

Šis vadovas pateikia pavyzdį, kaip sukurti skaitmeninį parašą naudojant RSA algoritmą Java kalboje. Skaitmeniniai parašai yra būtini norint patikrinti duomenų vientisumą ir autentiškumą įvairiose aplikacijose. Naudosime Java Signature API sukurti SHA1withRSA parašui ant nurodytų duomenų.

Reikalavimai

  • Java SE 8 ar naujesnė versija
  • RSA privatūs raktas pasirašymui

Kodo pavyzdys: SignatureCreator klasė

SignatureCreator klasė kaupia duomenis, kuriuos norite pasirašyti, ir tada sugeneruoja parašą naudodama pateiktą RSA privatų raktą.

import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.Signature;

public class SignatureCreator {

    private String algorithm = "SHA1withRSA";  // Parašymo algoritmas
    private StringBuilder data = new StringBuilder();  // Kaupia duomenis, kurie bus pasirašomi

    /**
     * Prideda duomenis prie parašo turinio.
     *
     * @param dataToAdd Pridedami tekstiniai duomenys
     */
    public void addData(String dataToAdd) {
        data.append(dataToAdd);
    }

    /**
     * Sugeneruoja parašą remiantis sukauptais duomenimis.
     *
     * @param privateKey RSA privatus raktas, naudojamas pasirašyti duomenis
     * @return Parašas kaip baitų masyvas
     * @throws Exception jei įvyksta klaida pasirašant
     */
    public byte[] sign(PrivateKey privateKey) throws Exception {
        Signature signature = Signature.getInstance(algorithm);
        signature.initSign(privateKey);
        signature.update(getBytesToBeSigned());
        return signature.sign();
    }

    /**
     * Konvertuoja sukauptus duomenis į baitus.
     *
     * @return Duomenų, kurie bus pasirašyti, baitų masyvas
     */
    private byte[] getBytesToBeSigned() {
        return data.toString().getBytes(StandardCharsets.UTF_8);
    }
}

Reikalavimai

Štai kaip naudoti SignatureCreator klasę pasirašyti duomenis:

  1. Inicializuokite SignatureCreator Klasę
SignatureCreator signatureCreator = new SignatureCreator();
  1. Pridėkite duomenis pasirašymui
  • Metodas addData leidžia pridėti duomenis po vieną dalį. Galite pridėti tiek duomenų eilučių, kiek reikia, klasė jas sujungs į vieną seką.
signatureCreator.addData("<clientId>client_id</clientId>");
signatureCreator.addData("<signerPersonalCode>signer_code</signerPersonalCode>");
signatureCreator.addData("<responseUrl>http://example.com/app</responseUrl>");
signatureCreator.addData("<signingType>Signature</signingType>");
signatureCreator.addData("<fileDigest>0v5NcpPFHEttzbsxm0urXlc5MIE=</fileDigest>");
signatureCreator.addData("<fileName>pdf.pdf</fileName>");
  1. Įkelkite RSA privatų raktą
  • Tarkime, kad jūsų RSA privatus raktas jau įkeltas kaip PrivateKey objektas.
 PrivateKey privateKey = loadPrivateKey(); // Įkelkite savo RSA privatų raktą
  1. Pasirašykite duomenis
  • Kai duomenys paruošti ir privatus raktas įkeltas, kvieskite sign(), kad sugeneruotumėte parašą.
try {
    byte[] signatureBytes = signatureCreator.sign(privateKey);
    String signatureBase64 = java.util.Base64.getEncoder().encodeToString(signatureBytes);
    System.out.println("Sugeneruotas Parašas (Base64): " + signatureBase64);
} catch (Exception e) {
    System.err.println("Klaida generuojant parašą: " + e.getMessage());
}

Pilnas pavyzdys

Štai pilnas naudojimo pavyzdys, kuris apjungia visus žingsnius:

import java.security.PrivateKey;
import java.security.Signature;
import java.util.Base64;

public class Main {
    public static void main(String[] args) {
        try {
            // Inicializuokite parašo kūrėją
            SignatureCreator signatureCreator = new SignatureCreator();

            // Pridėkite duomenis, kurie bus pasirašomi
            signatureCreator.addData("<clientId>client_id</clientId>");
            signatureCreator.addData("<signerPersonalCode>signer_code</signerPersonalCode>");
            signatureCreator.addData("<responseUrl>http://example.com/app</responseUrl>");
            signatureCreator.addData("<signingType>Signature</signingType>");
            signatureCreator.addData("<fileDigest>0v5NcpPFHEttzbsxm0urXlc5MIE=</fileDigest>");
            signatureCreator.addData("<fileName>pdf.pdf</fileName>");

            // Įkelkite savo privatų raktą
            PrivateKey privateKey = loadPrivateKey();

            // Sugeneruokite parašą
            byte[] signatureBytes = signatureCreator.sign(privateKey);
            String signatureBase64 = Base64.getEncoder().encodeToString(signatureBytes);

            // Parašas Base64 formatu
            System.out.println("Sugeneruotas Parašas (Base64): " + signatureBase64);

        } catch (Exception e) {
            System.err.println("Klaida generuojant parašą: " + e.getMessage());
        }
    }

    private static PrivateKey loadPrivateKey() {
        // Metodas, skirtas įkelti RSA privatų raktą (pakeiskite pagal jūsų rakto įkėlimo logiką)
        // Pavyzdžiui, naudojant rakto failą ir KeyFactory ir pan.
        return null;
    }
}

Parašo kūrimo paaiškinimas

  1. Inicializuojamas pasirašymo algoritmas: naudojame “SHA1withRSA” kaip algoritmą.
  2. Sujungiami duomenys pasirašymui: visi pridedami duomenys sujungiami į vieną seką. Įsitikinkite, kad pridėjote kiekvieną elementą reikiama tvarka.
  3. Konvertuojami duomenys į baitus: Kaupiami duomenys konvertuojami į UTF-8 baitus, kad būtų suderinami su kitomis sistemomis.
  4. Pasirašoma privačiu raktu: parašas generuojamas naudojant RSA privatų raktą, kuris sukuria unikalų parašą pateiktiems duomenims.

Parašo pavyzdys

Kai paleisite šį pavyzdį su savo privačiu raktu ir duomenimis, gausite parašą Base64 formatu:

Sugeneruotas Parašas (Base64): NkzVv5BN4o8apCRhi6J+kJXXBOfMWJDGocniq6eM4errlbFwOOrsW67iRh0hM6scaQ5Lzuf35/c3fgtHHeNPqXzHdQTRDtCBBfNUfHQrKt3gK6UEzfChBtfeO9tFiR80SJJ4trt+kcP197kR+6y8fjHCMcJUIt/NbXaFahf5qkU=

base64 encode reikšmė perduodama per signature užklausos elementą:

<signature>NkzVv5BN4o8apCRhi6J+kJXXBOfMWJDGocniq6eM4errlbFwOOrsW67iRh0hM6scaQ5Lzuf35/c3fgtHHeNPqXzHdQTRDtCBBfNUfHQrKt3gK6UEzfChBtfeO9tFiR80SJJ4trt+kcP197kR+6y8fjHCMcJUIt/NbXaFahf5qkU=</signature>

This site uses Just the Docs, a documentation theme for Jekyll.