Skip to content

SM4 online versleutelen en ontsleutelen

Versleutel en ontsleutel SM4 online. Mislukt ontsleutelen? De tool ziet of modus, padding, IV of codering fout is en geeft de oplossing. Draait in je browser, zonder upload. ECB, CBC, CTR, CFB, OFB; PKCS#7, zero of geen padding.

Geen tracking Draait in je browser Gratis
Versleutelen gebeurt volledig in je browser — de sleutel en data die je invoert, verlaten dit apparaat nooit.
Cijfertekst
Overeenkomend OpenSSL-commando

Vereist OpenSSL 3. Het commando bevat de sleutel die je hebt ingevoerd.

SM4-testvectoren uit GB/T 32907-2016

Bij het bouwen berekend door dezelfde engine die deze pagina gebruikt — toets je eigen SM4-implementatie eraan.
Sleutel 0123456789abcdeffedcba9876543210
Platte tekst 0123456789abcdeffedcba9876543210
Cijfertekst, 1 versleuteling 681edf34d206965e86b3e94f536e4246
Cijfertekst, 1.000.000 versleutelingen 595298c7c6fd271f0402f804c33d3f66
De SM4-engine is getest tegen beide vectoren uit bijlage A van GB/T 32907-2016 en vergeleken met OpenSSL 3 in ECB, CBC, CTR, CFB en OFB. De standaardinstellingen van de bibliotheken zijn gecontroleerd door OpenSSL, Node.js, sm-crypto, gm-crypt, gmssl en twee Go-bibliotheken daadwerkelijk uit te voeren, en door de broncode van Hutool en BouncyCastle te lezen. — Go Tools Security Team · Sep 11, 2026

Geschreven en beoordeeld door ontwikkelaars die cryptografische tools bouwen. Elke cijfertekst en elk aantal bytes op deze pagina is berekend door de engine van de tool en door tests gecontroleerd.

Snelle antwoorden over SM4

Sleutellengte van SM4

16 byte Precies 128 bit: 16 byte, geschreven als 32 hexcijfers of 16 ASCII-tekens. SM4-sleutels van 192 of 256 bit bestaan niet.

GB/T 32907-testvector

681edf34d206965e86b3e94f536e4246 Met sleutel en platte tekst 0123456789abcdeffedcba9876543210 geeft één versleuteling 681edf34d206965e86b3e94f536e4246.

Blokgrootte en rondes van SM4

32 rondes Blokken van 16 byte (128 bit), versleuteld in 32 rondes.

Geeft een verkeerde IV in CBC altijd een fout?

eerste 16 byte Nee. Alleen de eerste 16 byte ontsleutelen verkeerd, en de padding in het laatste blok klopt nog steeds.

Wat is SM4?

SM4 is het blokcijfer uit de Chinese standaarden voor commerciële cryptografie. Het verscheen als GM/T 0002-2012, werd de nationale standaard GB/T 32907-2016 (van kracht sinds 1 maart 2017) en is in 2021 via een amendement opgenomen in de internationale standaard ISO/IEC 18033-3. Het is een symmetrisch cijfer: dezelfde sleutel van 128 bit versleutelt en ontsleutelt, en het werkt met blokken van 128 bit, 16 byte per keer — dezelfde blokgrootte als AES.

Intern wordt elk blok opgesplitst in vier woorden van 32 bit, die 32 rondes doorlopen. Elke ronde mengt drie van de woorden met een rondesleutel, stuurt het resultaat door een 8-bit S-box en een lineaire transformatie, en voegt het samen met het vierde woord. De 32 rondesleutels worden uit de sleutel afgeleid met twee vaste reeksen constanten, en ontsleutelen is dezelfde berekening met de rondesleutels in omgekeerde volgorde.

Het kale blokcijfer verwerkt uitsluitend precies 16 byte, dus echte data gaat altijd door een bedrijfsmodus. Deze tool biedt de vijf klassieke: ECB en CBC, die met hele blokken werken en padding nodig hebben, en CTR, CFB en OFB, die van SM4 een streamcijfer maken zonder enige padding. De meeste mislukte ontsleutelingen hebben niets met SM4 zelf te maken — ze ontstaan doordat beide kanten het oneens zijn over de modus, de padding, de IV, de tekencodering of de manier waarop de sleutelstring bytes wordt, en bibliotheken zijn het zelfs niet eens over wat een kaal “SM4” betekent.

De ingebouwde Web Crypto API van browsers bevat geen SM4, dus deze pagina heeft een eigen implementatie aan boord die lokaal draait. Die is getest tegen de twee GB/T 32907-testvectoren en in elke modus vergeleken met OpenSSL 3.

// SM4-CBC with PKCS#7 padding using Node.js and its bundled OpenSSL 3.
// Key and IV are both exactly 16 bytes (32 hex digits).
const crypto = require('node:crypto');

const key = Buffer.from('0123456789abcdeffedcba9876543210', 'hex');
const iv = Buffer.from('fedcba98765432100123456789abcdef', 'hex');

const cipher = crypto.createCipheriv('sm4-cbc', key, iv);
const ciphertext = Buffer.concat([cipher.update('hello', 'utf8'), cipher.final()]);
console.log(ciphertext.toString('base64')); // fUQPRg2HAXHGz5ZslzCpSQ==

const decipher = crypto.createDecipheriv('sm4-cbc', key, iv);
const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
console.log(plaintext.toString('utf8')); // hello

Wat deze tool met SM4 kan

Vertelt je waarom ontsleutelen mislukte

Mislukt het ontsleutelen, dan probeert de pagina het opnieuw met een andere cijfertekstcodering, sleutelformaat, modus, IV, padding en tekencodering, en toont de instellingen die leesbare tekst opleveren.

Voorinstellingen voor de gangbare bibliotheken

Eén klik neemt de standaardinstellingen over van OpenSSL, Hutool, sm-crypto, gm-crypt of tjfoc/gmsm — bibliotheken die het niet eens zijn over de vraag of kaal “SM4” ECB of CBC betekent.

Vijf modi, drie soorten padding, UTF-8 of GBK

ECB, CBC, CTR, CFB en OFB met PKCS#7, zero padding of geen padding. Platte tekst kan UTF-8 of GBK zijn, de codering die oudere Java-code op een Chinees Windows-systeem oplevert. GCM wordt niet ondersteund.

SM4-sleutel en IV: willekeurig, of als hex, tekst of Base64

Genereer met één klik een willekeurige sleutel of IV van 16 byte, of voer hem in zoals je code hem schrijft. Een live byteteller bevestigt dat je precies 16 byte hebt voordat je andere oorzaken gaat zoeken.

GB/T 32907-testvectoren op de pagina

Beide resultaten uit bijlage A staan in een tabel en zijn met één klik te laden, zodat je elke SM4-implementatie aan de standaard kunt toetsen.

Overeenkomend OpenSSL-commando

Bij elk resultaat hoort het openssl enc-commando dat het reproduceert, zodat je het in een terminal kunt bevestigen of aan een collega kunt doorgeven.

Draait volledig in je browser

De SM4-engine draait lokaal. Sleutels en data verlaten de pagina nooit, en de tool blijft ook offline werken.

Standaardinstellingen voor SM4 in gangbare bibliotheken

OpenSSL 3 (openssl enc)

-sm4 = CBC

-sm4 is een alias van -sm4-cbc. -K en -iv verwachten hex, PKCS#7 blijft aan tenzij je -nopad meegeeft, en de uitvoer bestaat uit ruwe bytes tenzij je -base64 -A toevoegt. Een -K met de verkeerde lengte wordt afgekapt of met nullen aangevuld, met alleen een waarschuwing.

Java: Hutool SmUtil.sm4(key)

ECB · PKCS#7

Hutool geeft een kaal SM4 door, dat BouncyCastle uitvoert als ECB met PKCS#7 (JCE noemt dat PKCS5Padding). Stringmethoden gebruiken UTF-8 en encryptHex geeft hex in kleine letters. Gebruik voor CBC new SM4(Mode.CBC, Padding.PKCS5Padding, key, iv).

Java: BouncyCastle Cipher.getInstance("SM4")

ECB · PKCS#7

Krijgt een modus die een IV nodig heeft er geen, dan genereert versleutelen stilzwijgend een willekeurige IV en gooit ontsleutelen no IV set when one expected — cijfertekst die is versleuteld zonder die IV te bewaren, kan dus nergens meer worden ontsleuteld.

JavaScript: sm-crypto

ECB · hexsleutel

sm4.encrypt(data, key) gebruikt standaard ECB met PKCS#7, verwacht de sleutel als hexstring van 32 cijfers en geeft hex in kleine letters terug. Alleen mode: 'cbc' verandert de modus; bij elke andere waarde blijft het stilzwijgend ECB. sm-crypto-v2 gedraagt zich hetzelfde, maar gebruikt een IV van alleen nullen als CBC geen iv krijgt.

JavaScript: gm-crypt

CBC · tekstsleutel · Base64

Gebruikt standaard CBC, neemt sleutel en IV als UTF-8-strings van 16 tekens en geeft Base64 terug. Een sleutel waarvan de bytes geen geldige UTF-8 zijn, kun je er helemaal niet aan meegeven.

Python: gmssl CryptSM4

PKCS#7 · sleutel afgekapt tot 16 byte

Je kiest de modus door crypt_ecb of crypt_cbc aan te roepen. set_key leest alleen de eerste 16 byte, dus een langere sleutel wordt stilzwijgend afgekapt, en een verkeerde sleutel levert meestal lege bytes op in plaats van een fout.

Go: tjfoc/gmsm sm4

standaard een IV van nullen

Sm4Cbc gebruikt een IV op pakketniveau die uit nullen blijft bestaan tot SetIV wordt aangeroepen, past zelfs in CFB en OFB PKCS#7-padding toe en negeert fouten bij het verwijderen van de padding — een verkeerde sleutel geeft nil terug zonder fout.

Voorbeelden van versleutelen en ontsleutelen met SM4

GB/T 32907-testvector (ECB, geen padding)

Sleutel 0123456789abcdeffedcba9876543210, platte tekst (hex) 0123456789abcdeffedcba9876543210
681edf34d206965e86b3e94f536e4246

Dit is voorbeeld 1 uit bijlage A van GB/T 32907-2016: sleutel en platte tekst zijn dezelfde waarde van 128 bit, en één versleuteling geeft 681edf34d206965e86b3e94f536e4246. Versleutel je die uitvoer telkens opnieuw, in totaal een miljoen keer, dan krijg je 595298c7c6fd271f0402f804c33d3f66. Beide waarden staan in de testvectortabel op deze pagina, berekend door dezelfde engine die jij gebruikt. De knop GB/T 32907-testvector laadt de eerste.

CBC met PKCS#7: tekst erin, Base64 eruit

Sleutel 0123456789abcdeffedcba9876543210, IV fedcba98765432100123456789abcdef, platte tekst: SM4 interop test: order 20260911-0042
Wi6BuLpov8RndEfedUyLXFvDRnLMoo7T6O04Q83IzKDuDvPQ2S5clq+cEQXMvy/y

De platte tekst is 37 byte UTF-8. PKCS#7 vult die aan tot 48 byte, drie blokken van 16 byte, en in Base64 wordt dat 64 tekens. De knop Voorbeeld laden vult precies deze waarden in, en het OpenSSL-paneel toont een commando dat dezelfde Base64-string in een terminal reproduceert.

Verkeerde IV in CBC: alleen de eerste 16 byte gaan stuk

De cijfertekst hierboven, ontsleuteld met IV 00000000000000000000000000000000
16 byte onzin, dan ": order 20260911-0042"

CBC mengt de IV alleen in het eerste blok, en de PKCS#7-padding zit in het laatste blok, dus de paddingcontrole slaagt gewoon en OpenSSL geeft geen fout. Deze pagina merkt het onleesbare eerste blok op en vertelt je dat sleutel en modus kloppen en dat de IV het probleem is — of dat de eerste 16 byte van de cijfertekst zelf de IV zijn.

Zo versleutel en ontsleutel je met SM4

  1. 1

    Kies een bibliotheekvoorinstelling, of de modus en padding

    Weet je welke bibliotheek de andere kant gebruikt, kies die dan onder Standaardinstellingen van. Kies anders Versleutelen of Ontsleutelen en stem modus en padding af. Streammodi (CTR, CFB, OFB) hebben geen padding, dus de paddingkeuze is voor die modi uitgeschakeld.

  2. 2

    Voer de sleutel en IV in

    Beide zijn precies 16 byte. Kies het formaat waarin de string is geschreven — hex, tekst of Base64 — en kijk of de byteteller groen wordt. De knoppen Willekeurig genereren nieuwe waarden.

  3. 3

    Plak de invoer

    Typ bij versleutelen tekst (UTF-8 of GBK) of plak hexbytes. Plak bij ontsleutelen de cijfertekst en geef aan of die Base64 of hex is. Het resultaat wordt bijgewerkt terwijl je typt.

  4. 4

    Kopieer het resultaat of controleer de round-trip

    Kopieer de uitvoer, of klik op Deze cijfertekst ontsleutelen om hem met dezelfde sleutel en IV naar het tabblad Ontsleutelen te brengen. Het OpenSSL-paneel toont een commando dat het resultaat reproduceert.

  5. 5

    Lees de diagnose als ontsleutelen mislukt

    De diagnose somt de instellingen op waarmee je invoer tot leesbare tekst ontsleutelt. Pas er één toe met een klik, of lees de melding als alleen de eerste 16 byte mislukken — dat wijst op de IV.

Waarom ontsleutelen met SM4 mislukt

Een hexsleutel als tekst lezen

Een hexstring van 32 tekens is alleen 16 byte als hij als hex wordt gedecodeerd. Als tekst gelezen is hij 32 byte, wat SM4 weigert — of, in code die sleutels stilzwijgend afkapt of aanvult, een heel andere sleutel.

✗ Fout
Sleutel (tekst): 0123456789abcdeffedcba9876543210  -> 32 byte, geweigerd
✓ Correct
Sleutel (hex):   0123456789abcdeffedcba9876543210  -> 16 byte

CBC-cijfertekst als ECB ontsleutelen

Beide kanten moeten dezelfde modus gebruiken. CBC-cijfertekst die als ECB wordt ontsleuteld, levert in elk blok onzin op en faalt meestal op de paddingcontrole aan het eind.

✗ Fout
versleutelen: SM4/CBC/PKCS5Padding
ontsleutelen: SM4/ECB/PKCS5Padding  -> bad decrypt
✓ Correct
versleutelen: SM4/CBC/PKCS5Padding
ontsleutelen: SM4/CBC/PKCS5Padding, zelfde IV

Een andere IV gebruiken

In CBC geeft een verkeerde IV geen fout: de eerste 16 byte komen verminkt uit en de rest ontsleutelt normaal. Is alleen het begin van je platte tekst kapot, vergelijk dan de IV's.

✗ Fout
ontsleutelen met IV 00000000000000000000000000000000
-> 16 byte onzin + ": order 20260911-0042"
✓ Correct
ontsleutelen met IV fedcba98765432100123456789abcdef
-> "SM4 interop test: order 20260911-0042"

Base64-cijfertekst als hex behandelen

Base64 en hex zijn twee manieren om dezelfde bytes op te schrijven. Lees je het ene als het andere, dan krijgt het cijfer vanaf het begin de verkeerde invoer.

✗ Fout
Wi6BuLpov8RndEfedUyLXFvDRnLMoo7T6O04Q83IzKDuDvPQ2S5clq+cEQXMvy/y  als hex gelezen -> ongeldig
✓ Correct
Wi6BuLpov8RndEfedUyLXFvDRnLMoo7T6O04Q83IzKDuDvPQ2S5clq+cEQXMvy/y  als Base64 gelezen -> 48 byte

Zero padding die echte nullen aan het eind wist

Zero padding kan padding niet van data onderscheiden, dus platte tekst die echt op 0x00 eindigt, raakt die bytes kwijt. Gebruik PKCS#7 voor alles wat geen gewone tekst is.

✗ Fout
zero padding: 61 62 00  -> ontsleutelt tot 61 62
✓ Correct
PKCS#7:       61 62 00  -> ontsleutelt tot 61 62 00

Aannemen dat “SM4” overal dezelfde modus betekent

OpenSSL behandelt sm4 als CBC. BouncyCastle — en dus ook SmUtil.sm4(key) in Hutool — behandelt SM4 als ECB met PKCS#7. Twee systemen die allebei “gewoon SM4 gebruiken”, kunnen het dus oneens zijn over de modus.

✗ Fout
Java:    Cipher.getInstance("SM4")  -> ECB + PKCS#7
OpenSSL: openssl enc -sm4           -> CBC
✓ Correct
Java:    Cipher.getInstance("SM4/CBC/PKCS5Padding")
OpenSSL: openssl enc -sm4-cbc

Aan de ene kant GBK-bytes versleutelen, aan de andere kant UTF-8

getBytes() zonder tekenset gebruikt in Java de standaard van het platform, en dat is GBK op een Chinese Windows-installatie met JDK 17 of ouder. Dezelfde Chinese tekst versleutelt dan tot andere cijfertekst, en de andere kant ontsleutelt die tot mojibake.

✗ Fout
"国密SM4 test".getBytes()  // GBK op Chinese Windows met JDK <= 17
-> ECB-cijfertekst 3188d06cf28db70092f8753cbd5ee518
✓ Correct
"国密SM4 test".getBytes(StandardCharsets.UTF_8)
-> ECB-cijfertekst d830308b0ae4fa7b9a2b5d59f7f65ca5

Wanneer je SM4 online nodig hebt

SM4-uitvoer van backend en frontend op elkaar afstemmen
Je Java-service en je webclient leveren voor dezelfde tekst verschillende cijfertekst op. Reproduceer hier elke kant met de bijbehorende bibliotheekvoorinstelling en zie welke parameter verschilt.
Een mislukte ontsleuteling uit een partnersysteem debuggen
Een partner stuurt SM4-cijfertekst die niet wil ontsleutelen. Plak die met de afgesproken sleutel en IV en laat de diagnose uitzoeken welke modus, padding of codering de partner werkelijk heeft gebruikt.
Een SM4-implementatie verifiëren
Toets je code aan de GB/T 32907-vectoren op deze pagina en vergelijk daarna een CBC-round-trip, voordat de implementatie ook maar in de buurt van productiedata komt.
Testdata voorbereiden voor een migratie naar SM4
Stapt een systeem over van AES op SM4, genereer dan hier bekende combinaties van sleutel, IV en cijfertekst om als fixtures in de nieuwe tests te gebruiken.
Zien hoe blokcijfermodi zich gedragen
Versleutel twee identieke blokken in ECB en CBC, of ontsleutel met een verkeerde IV, en kijk wat er in de cijfertekst en in de uitvoer verandert.

Zo werken SM4 en de bedrijfsmodi

Blokgrootte, sleutelgrootte en rondes
SM4 versleutelt blokken van 128 bit met een sleutel van 128 bit in 32 rondes. Elke ronde past een 8-bit S-box toe op een woord van 32 bit en daarna een lineaire transformatie die het woord via XOR combineert met vier rotaties van zichzelf. Ontsleutelen doorloopt dezelfde 32 rondes met de rondesleutels in omgekeerde volgorde.
ECB: elk blok op zichzelf
ECB versleutelt elk blok van 16 byte onafhankelijk. Er is geen IV nodig, maar gelijke blokken platte tekst worden gelijke cijfertekstblokken, waardoor patronen in de data zichtbaar blijven. Tenzij de invoer een veelvoud van 16 byte is, heeft ECB padding nodig.
CBC: gekoppelde blokken en een IV
CBC combineert elk blok platte tekst via XOR met het vorige cijfertekstblok voordat het wordt versleuteld, en gebruikt de IV voor het eerste blok. Omdat de IV alleen in het eerste blok terechtkomt, beschadigt een verkeerde IV precies de eerste 16 byte van de platte tekst en blijft de padding in het laatste blok intact, waardoor er vaak helemaal geen fout optreedt.
CTR, CFB en OFB: SM4 als streamcijfer
Deze modi versleutelen een teller of feedbackwaarde en combineren het resultaat via XOR met de data, waardoor de cijfertekst even lang is als de platte tekst en er geen padding is. In CTR wordt de hele IV van 16 byte opgehoogd als één big-endian teller van 128 bit, net als in OpenSSL. Een verkeerde IV verminkt in CTR en OFB het hele bericht, maar in CFB alleen het eerste blok.
Regels voor padding
PKCS#7 voegt 1 tot 16 byte met de waarde n toe, dus een bericht dat al uit hele blokken bestaat, krijgt toch een volledig blok padding. Zero padding voegt alleen waar nodig 0x00-bytes toe en verwijdert bij het ontsleutelen alle nullen aan het eind. Geen padding laat de data ongewijzigd en weigert invoer die geen hele blokken vult.

Aanbevolen aanpak voor SM4

Kies geen ECB voor nieuwe ontwerpen
ECB verraadt welke blokken gelijk zijn. Gebruik CBC of CTR, tenzij je moet aansluiten op een bestaand systeem dat al ECB gebruikt.
Gebruik voor elk bericht een nieuwe willekeurige IV
De IV is niet geheim, maar mag onder dezelfde sleutel niet terugkomen. Genereer hem voor elk bericht willekeurig en bewaar of verstuur hem naast de cijfertekst.
Authenticeer de cijfertekst
GB/T 17964-2021, de Chinese standaard voor bedrijfsmodi van blokcijfers, stelt dat de beschreven modi de vertrouwelijkheid beschermen, niet de integriteit. Verander in CBC één byte van de IV en pay=100.00 wordt pay=900.00, terwijl het ontsleutelen gewoon slaagt. Bereken een MAC over de IV en de cijfertekst en controleer die vóór het ontsleutelen, bijvoorbeeld met de HMAC-generator.
Leg elke parameter vast in de interfacespecificatie
“Versleuteld met SM4” is geen specificatie. Leg vast welke modus en padding je gebruikt, hoe sleutel en IV zijn geëncodeerd, welke tekenset de platte tekst heeft en of de cijfertekst hex of Base64 is.
Houd echte sleutels uit webpagina's en broncode
Gebruik deze pagina met testsleutels. Productiesleutels horen in een sleutelbeheersysteem of hardware security module en worden tijdens runtime geladen, niet in een formulier geplakt of in de repository gezet.

Veelgestelde vragen over SM4

Waarom mislukt mijn SM4-ontsleuteling met een padding-fout of onleesbare tekst?
Ontsleutelen werkt alleen als alles overeenkomt met de kant die versleutelde: de sleutelbytes, de modus, de IV, de padding en de manier waarop de cijfertekst is opgeschreven (hex of Base64). De fout die je krijgt — “bad decrypt”, een padding-exception of een scherm vol onzin — zegt niet welke van die dingen niet klopt, en sommige bibliotheken geven zelfs lege uitvoer terug in plaats van een fout. Plak de cijfertekst, sleutel en IV hier toch. Mislukt het ontsleutelen, dan probeert de pagina elke combinatie van cijfertekstcodering, sleutelformaat, modus, IV en padding — inclusief sleutels die een bibliotheek stilzwijgend tot 16 byte heeft afgekapt en platte tekst die als GBK is geëncodeerd — en somt de lezingen op die leesbare tekst opleveren, met een markering bij de lezingen waarvan de PKCS#7-padding klopte. Komen alleen de eerste 16 byte verkeerd uit, dan kloppen sleutel en modus en is de IV fout.
Hoe lang is een SM4-sleutel, en kan hij 256 bit zijn?
Een SM4-sleutel is precies 128 bit, oftewel 16 byte — even groot als het blok. GB/T 32907 definieert alleen deze ene sleutellengte; SM4 met 192 of 256 bit bestaat niet. Vraagt iemand om een SM4-sleutel van 256 bit, controleer dan of een hexstring van 32 cijfers is geteld als 32 tekens van elk 8 bit. Zestien byte kun je schrijven als 32 hexcijfers of als 16 ASCII-tekens, en die twee door elkaar halen is de meest voorkomende sleutelfout: 0123456789abcdeffedcba9876543210 als hex gelezen is 16 byte, maar dezelfde string als tekst gelezen is 32 byte en wordt geweigerd. De formaatkeuze en de byteteller naast het sleutelveld zijn er precies om dit op te vangen.
Wat is de IV bij SM4, en hoe lang moet die zijn?
De IV (initialisatievector) is een waarde van 16 byte die in CBC, CTR, CFB en OFB in het eerste blok wordt gemengd; ECB gebruikt er geen. Hij moet precies 16 byte zijn — 32 hexcijfers of 16 ASCII-tekens — dus krijg je een fout over de IV-lengte, controleer dan of een hexstring van 32 cijfers is gelezen als 32 byte tekst. De IV is niet geheim, maar mag onder dezelfde sleutel niet terugkomen: genereer hem willekeurig en stuur hem mee met de cijfertekst, vaak ervoor. Een verkeerde IV in CBC geeft meestal geen fout en verminkt alleen de eerste 16 byte. Sommige bibliotheken gebruiken stilzwijgend een IV van alleen nullen als je er geen opgeeft (sm-crypto-v2, tjfoc/gmsm in Go), terwijl BouncyCastle in Java een willekeurige genereert — wordt die IV niet bij de cijfertekst bewaard, dan kan niemand de cijfertekst meer ontsleutelen.
Wat is het verschil tussen SM4 ECB en CBC, en welke moet ik gebruiken?
Gebruik CBC (of CTR) met een nieuwe willekeurige IV voor elk bericht. ECB versleutelt gelijke blokken van 16 byte tot gelijke cijfertekstblokken, waardoor herhaalde structuur in de data zichtbaar blijft in de cijfertekst. Kies ECB alleen om te communiceren met een systeem dat het al gebruikt. Let op: geen van beide modi detecteert manipulatie. Is dat belangrijk, stuur dan ook een MAC over de IV en de cijfertekst mee, bijvoorbeeld met de HMAC-generator.
Welke SM4-padding moet ik gebruiken: PKCS5Padding, PKCS#7, zero padding of geen padding?
PKCS#7 voegt altijd 1 tot 16 byte toe, die elk het aantal toegevoegde bytes bevatten, zodat de ontvanger de padding ondubbelzinnig kan verwijderen. Voor een blokcijfer van 16 byte zoals SM4 is PKCS5Padding in Java dezelfde padding — BouncyCastle stuurt beide namen door hetzelfde codepad. Zero padding vult alleen met 0x00 aan tot de volgende blokgrens. Bij het ontsleutelen verwijderen Hutool en BouncyCastle elke 0x00 aan het eind, ook nulbytes die echt bij de data hoorden, terwijl gmssl in Python er maar één verwijdert. Geen padding vereist dat de invoer uit een geheel aantal blokken van 16 byte bestaat. CTR, CFB en OFB zijn streammodi en gebruiken nooit padding. Eindigt ontsleutelde tekst op losse spaties, vakjes of regeleinden, dan is de padding niet verwijderd: PKCS#7-data die zonder padding is ontsleuteld, houdt aan het eind n byte met de waarde n over (0x09, 0x0A en 0x0D verschijnen als tabs en regeleinden); zet de uitvoer op Hex en bekijk het laatste blok.
Hoe lang is SM4-cijfertekst, en kun je er de modus aan zien?
Tel in bytes. Met PKCS#7 in ECB of CBC wordt de platte tekst naar boven afgerond op het volgende veelvoud van 16, en een bericht dat al een veelvoud van 16 is, krijgt er nog een volledig blok bij — 5 of 15 byte worden 16, en 16 byte worden 32. Zero padding vult alleen aan tot het volgende veelvoud van 16, zonder padding blijft de lengte gelijk, en cijfertekst in CTR, CFB en OFB is precies even lang als de platte tekst. Hex verdubbelt het aantal bytes; Base64 gebruikt 4 × ⌈bytes / 3⌉ tekens, dus 16 byte zijn 24 tekens, 32 zijn er 44 en 64 zijn er 88. Tel er 16 byte bij op als de IV vooraan wordt meegestuurd. De cijfertekst alleen verraadt de modus niet, maar twee aanwijzingen helpen: een lengte die geen veelvoud van 16 is, sluit ECB of CBC met padding vrijwel uit, en twee identieke blokken van 16 byte wijzen op ECB. Twijfel je, plak de cijfertekst dan in het tabblad Ontsleutelen: de automatische diagnose probeert de modi voor je.
Geeft SM4 elke keer dezelfde cijfertekst, en waarom wijkt de uitvoer van een andere tool af?
ECB — of elke modus met een vaste IV — geeft voor dezelfde sleutel en platte tekst elke keer dezelfde cijfertekst; met bij elke run een nieuwe willekeurige IV verandert de uitvoer elke keer, zoals het hoort. Vergelijk daarnaast de modus, de padding, of de sleutel als hex of als tekst is gelezen, hoe de platte tekst is geëncodeerd — UTF-8 in de meeste code, maar GBK wanneer oudere Java-code getBytes() aanroept op een Chinees Windows-systeem — en hoe het resultaat wordt weergegeven: Base64, hex in kleine letters of hex in hoofdletters. Met identieke instellingen en een vaste IV leveren twee correcte implementaties identieke uitvoer op. Verdenk je een van beide tools, toets ze dan eerst allebei aan de GB/T 32907-testvector.
Hoe controleer ik of mijn eigen SM4-implementatie klopt?
Begin met de twee vectoren uit bijlage A van GB/T 32907-2016. Met sleutel en platte tekst allebei 0123456789abcdeffedcba9876543210 moet één versleuteling 681edf34d206965e86b3e94f536e4246 opleveren en een miljoen versleutelingen achter elkaar 595298c7c6fd271f0402f804c33d3f66. Die testen alleen het blokcijfer, dus versleutel daarna wat tekst in CBC met een vaste sleutel en IV en vergelijk het resultaat met deze pagina of met het OpenSSL-commando dat hier wordt getoond. De engine achter deze pagina is getest tegen beide vectoren en tegen OpenSSL 3 in alle vijf de modi.
Kan OpenSSL SM4 versleutelen en ontsleutelen?
Ja. OpenSSL 3 ondersteunt SM4 in ECB, CBC, CFB, OFB en CTR. Gebruik openssl enc -sm4-cbc -K <32 hex digits> -iv <32 hex digits>: -K neemt de ruwe sleutel in hex, er komt dus geen wachtwoord aan te pas, -nopad zet PKCS#7 uit, en -base64 -A leest of schrijft Base64 op één regel. Let op twee dingen: kaal -sm4 betekent CBC, en een -K-waarde met de verkeerde lengte wordt afgekapt of met nullen aangevuld, met alleen een waarschuwing. Het OpenSSL-paneel op deze pagina stelt het commando samen uit je huidige instellingen; openssl enc kent geen zero padding, dus het paneel meldt dat in plaats van een commando te tonen dat niet zou overeenkomen.
Hoe ontsleutel ik SM4-cijfertekst uit Java (Hutool) of JavaScript (sm-crypto)?
Zoek eerst uit welke modus en padding de andere kant echt gebruikt — vaak staat dat nergens in de code. SmUtil.sm4(key) in Hutool geeft alleen de naam SM4 door, en BouncyCastle vult dan ECB met PKCS#7 in (in Java PKCS5Padding); alleen een volledige string zoals SM4/CBC/PKCS5Padding betekent CBC. In JavaScript gebruikt sm-crypto standaard ook ECB, verwacht het de sleutel als hexstring van 32 cijfers en geeft het hex in kleine letters terug, terwijl gm-crypt standaard CBC gebruikt, een tekstsleutel van 16 tekens verwacht en Base64 teruggeeft. Controleer daarna de tekenset van de platte tekst: de stringmethoden van Hutool gebruiken altijd UTF-8, maar een kale getBytes() op JDK 17 of ouder op een Chinees Windows-systeem kan GBK betekenen, en dan verandert de cijfertekst. Kies de bibliotheek onder Standaardinstellingen van om dit allemaal met één klik in te stellen, of vul het zelf in; twijfel je over een van de instellingen, plak de cijfertekst dan toch: de automatische diagnose probeert de combinaties van modus, padding, IV en codering.
Is SM4 veilig, en wordt mijn data geüpload?
Als algoritme gebruikt SM4 een sleutel van 128 bit en 32 rondes; RFC 8998 (2021) stelt dat er op het moment van schrijven geen zwakke sleutels of beveiligingsproblemen van SM4 bekend waren. De praktische risico's zitten in hoe het wordt gebruikt: ECB lekt patronen en CBC detecteert geen manipulatie. Wat deze pagina betreft: er gaat niets naar een server. Browsers leveren SM4 niet mee, dus deze pagina heeft een eigen SM4-implementatie aan boord die lokaal draait; je kunt het netwerkpaneel openen en zien dat er geen verzoek vertrekt, of de verbinding verbreken en de tool gewoon blijven gebruiken. Daarmee is de tool prima geschikt voor testdata, debuggen en leren. Een webpagina wordt daardoor nog niet de juiste plek voor productiesleutels: die horen in een sleutelbeheersysteem of hardwaremodule, niet in een tekstvak op welke website dan ook.
Wat is het verschil tussen SM4 en AES?
Beide zijn blokcijfers met blokken van 128 bit, en de modi en padding werken bij beide op dezelfde manier — daarom lijken interoperabiliteitsbugs met SM4 precies op die met AES. SM4 doorloopt 32 rondes en heeft één sleutellengte van 128 bit; AES-128 doorloopt 10 rondes, en AES kent daarnaast sleutels van 192 en 256 bit. SM4 is de Chinese nationale standaard GB/T 32907-2016 en maakt sinds 2021 naast AES deel uit van de internationale standaard ISO/IEC 18033-3; het wordt gebruikt waar Chinese commerciële cryptografie vereist is. AES is de NIST-standaard FIPS 197. Voor AES gebruik je de AES-versleutelingstool.

Gerelateerde tools

Alle tools bekijken →