Zephyrnet-logo

Hoe Smart Card NFC-chips veilig sleutelbeheer in Blockchain-oplossingen verbeteren

Datum:

beeld

Lisk Hacker Noon profielfoto

@LiskLisk

We bieden ontwikkelaars een softwareontwikkelingskit voor blockchaintoepassingen die in JavaScript zijn geschreven.

Een grote uitdaging bij veel blockchain-oplossingen is om fysieke actoren of objecten veilig te verbinden met hun digitale representatie in de blockchain. Enkele voor de hand liggende voorbeelden zijn supply chain- en anti-namaakoplossingen, waarbij digitale informatie met betrekking tot de productie, oorsprong, chain of custody of verzendingsvoorwaarden onveranderlijk is beveiligd in de blockchain.

In de meeste oplossingen worden openbare/private sleutelparen die digitale en fysieke actoren, machines of goederen vertegenwoordigen, op afstand beheerd in externe of cloudserver-backends. Aangezien eigendom, identificatie en vertrouwen in blockchain-oplossingen worden overgedragen via de controle van privésleutels, vormen externe sleutelbeheersystemen op zijn best een dure en moeizame aangelegenheid, en een serieuze aangelegenheid. veiligheidsrisico in het slechtste geval. Door het sleutelbeheerproces dichter bij de objecten van belang te brengen, bespaart u dus niet alleen waardevolle bronnen; het voegt een aanzienlijke vertrouwenslaag toe aan de oplossing.

In dit artikel beschrijven we hoe smartcard NFC-chips met blockchain-capaciteiten kunnen worden gebruikt voor veiliger sleutelbeheer in blockchain-oplossingen, en specifiek in oplossingen die zijn gebouwd met de Lisk SDK en JavaScript.

Allereerst beschrijven we kort de technologie die Gimly hiervoor gebruikt. Ten tweede beschrijven we het Smart Transport proof-of-concept dat is gebouwd door Marc Buma en Caspar Roelofs en dat is gefinancierd via het Lisk Builders-programma. Ten slotte duiken we wat dieper in de code, om in meer detail te laten zien hoe de microchips interageren met de Lisk-blockchain in onze JavaScript-codebasis.

Tangem van Gimly: gemaakt voor blockchain NFC-chips

Gimly werkt met Tangem als leverancier en implementatiepartner om een ​​nieuwe benadering te bieden voor een veiliger beheer van openbare/private sleutelparen in blockchain-oplossingen. De voor blockchain gemaakte NFC-smartcardchips van Tangem zijn EAL6+-gecertificeerd en bevatten een beveiligd element waarbij de sleutelparen nieuw worden gegenereerd en waarvan de privésleutel niet kan worden geëxtraheerd, zichtbaar of gekopieerd.

De firmware van de chip maakt het gebruik van deze op zichzelf staande sleutels mogelijk om blockchain-transacties rechtstreeks vanaf de chip te ondertekenen en om versleutelde gegevens te ondertekenen, op te slaan en te presenteren met behulp van de beveiligde opslag. Chipbewerkingen worden beschermd door middel van verschillende beveiligingsopties (waaronder 2FA, toegangscodes en meerdere pincodes) en de firmware wordt onafhankelijk gecontroleerd door beveiligingsbedrijf Kudelski.

De chips zijn beschikbaar hier in verschillende vormfactoren, waaronder duurzaam fysiek creditcardformaat, zelfklevende stickers of tags. Het fysieke kaartformaat is momenteel beschikbaar als vooraf ingerichte crypto-notes voor alle belangrijke cryptocurrencies, of als ontwikkelaarskaarten die kunnen worden ingericht om te werken met elke blockchain die secp256 of ed25519 cryptografische curven gebruikt, inclusief Lisk.

beeld
beeld
beeld
beeld

Lisk-bouwers: Smart Transport PoC

De Smart Transport PoC maakt gebruik van een Tangem smartcard om te demonstreren hoe een hardware wallet kan worden gebruikt om een ​​pakket te beveiligen met behulp van de Lisk SDK. In deze demonstratie is een nieuwe client-applicatie ontwikkeld voor de Lisk Transport-demo die een NFC-lezer gebruikt om te communiceren met een Tangem-smartcard.

beeld

In de demo gaan we ervan uit dat de smartcard onderdeel is van een slimme container, dat wil zeggen een container beveiligd met een eigen hardware wallet die wordt gebruikt om alle metingen van de temperatuur en alarmcondities die de container meldt te ondertekenen. Tijdens het transport kunnen alle bij het transport aangesloten partijen (klant, leverancier en ontvanger) de publieke sleutel voor de slimme container bepalen en zo verifiëren dat de ontvangen gegevens ook daadwerkelijk van dit transport afkomstig zijn.

Wanneer de slimme container klaargemaakt wordt voor een nieuw transport, wordt er een nieuw account aangemaakt op de smartcard die uniek is voor dit transport. Dit account wordt automatisch gefinancierd met een bepaalde LSK om autonoom transacties te kunnen indienen.

Terwijl het transport aan de gang is, worden alle transacties die afkomstig zijn van de slimme container (metingen, alarmen) ondertekend door deze rekening, waarmee hun oorsprong en authenticiteit wordt bewezen.

Zodra het transport is voltooid, wordt overtollige LSK van de rekening geretourneerd en wordt de rekening gewist. Nu kan de slimme container ingezet worden voor een nieuw transport.

De demo voegt de volgende elementen toe aan het Lisk Transport-voorbeeld:

  • Een driver voor PC/SC-compatibele smartcardlezers. In onze demonstratie gebruiken we een ACS ACR1252-lezer. Deze driver wordt gebruikt om de smartcardlezer te pollen.
  • Een driver voor het Tangem-protocol die alle functies implementeert die nodig zijn om bovenstaande stappen mogelijk te maken (portemonnee aanmaken, portemonnee opschonen, transactiehashes ondertekenen met de smartcard).
  • Implementatie van de register-maat transactie op maat.
  • Een nieuwe klantapplicatie die wordt gebruikt om het transport te starten en te beëindigen en waarmee metingen kunnen worden gesimuleerd.
  • Een nieuwe IoT-toepassing die de smartcardlezer gebruikt om gesimuleerde temperatuurmetingen te ondertekenen.
  • Visualisatie van temperatuurgegevens die tijdens het transport op de blockchain zijn opgeslagen.

Hands-on met de demo

Aangezien deze demo voortbouwt op de Lisk Transport workshop, dient u in ieder geval door te gaan naar stap 0 (Workshop Part 0: Installatie en configuratie) voor het starten. Op dit punt zou u een actieve blockchain moeten hebben waarop alle vereisten zijn geïnstalleerd.

Bovendien moet u ervoor zorgen dat de juiste PC/SC-stuurprogramma's voor uw NFC-lezer zijn geïnstalleerd.

Nu kunt u de bronnen van de demo naar een map op uw harde schijf klonen. De repository is te vinden hier.

De projectroot voor de volgende stappen bevindt zich in de gimly-transport map.

De demonstratie maakt gebruik van 3 terminalvensters:

Eerste venster waarop de blockchain draait

  • Navigeer naar de hoofdmap van het project
  • Installeer de knooppuntafhankelijkheden in de transactiemap
    ○cd-transacties
    ○npm installeren
  • Installeer de knooppuntafhankelijkheden in de tangem-smart map
    ○ cd ../tangem-smart
    ○npm installeren
  • Navigeer vervolgens naar de node-map en start de blockchain
    ○ cd ../knooppunt
    ○npm installeren
    ○ node index.js | npx bunyan -o kort

Tweede venster waarop de clienttoepassing wordt uitgevoerd

  • navigeer naar de hoofdmap van het project
    ○cd-client
    ○npm installeren
    ○ knooppunt app.js

Derde venster waarop de IoT-toepassing wordt uitgevoerd

  • navigeer naar de hoofdmap van het project
    ○ cd iot/temperatuur_en_vochtigheid
    ○npm installeren
    ○ knooppunt index.js

Nu kunt u verbinding maken met uw laptop om de clienttoepassing te bekijken door te openen http://localhost:3000 in uw web browser.

Stap 1: Plaats de smartcard op de NFC-lezer

beeld

Selecteer een van de smartcards en plaats deze op de lezer. Druk nu op vernieuwen. De applicatie herkent de kaart en stelt u in staat een nieuwe zending aan te maken. Als de smartcard al in gebruik is, wordt de status van het huidige transport weergegeven (stap 3, 4 of 5, afhankelijk van de transportstatus).

Stap 2: Zending aanmaken

beeld

Selecteer eerst een van de demo-accounts als afzender voor dit pakket. Zorg ervoor dat de afzender voldoende geld heeft, anders mislukt het maken van de zending (u kunt de fondsknop gebruiken om wat LSK uit de kraan te halen).

Selecteer vervolgens de ontvanger en stel de transportvoorwaarden in (verzendkosten en beveiliging). Houd het vertrouwensniveau op 0 voor uw eerste transport. Naarmate u meer transport simuleert, zal het vertrouwensniveau van de in dienst zijnde vervoerder toenemen.

Druk tot slot op aanmaken om de zending aan te maken. Houd het terminalvenster in de gaten zodat de klant kan zien wat er gebeurt:

  • Eerst wordt er een nieuw wallet-account aangemaakt op de smartcard.
  • Vervolgens ontvangt de portemonnee wat geld uit de kraan met een overboekingstransactie.
  • Ten slotte wordt de nieuwe zending geregistreerd op de blockchain met een register-pakkettransactie.

Wanneer deze acties zijn voltooid, zal de browser u hiervan op de hoogte stellen:

beeld

Druk op terug om terug te keren naar de hoofdpagina.

Stap 3: Start transport

beeld

Zorg er eerst voor dat de vervoerder voldoende geld heeft om de borg te betalen (u kunt de fondsknop gebruiken om wat LSK uit de kraan te halen).

Druk vervolgens op “start transport”. Er wordt nu een start-transport transactie naar de blockchain gestuurd. Wanneer de transactie is verzonden, zal de browser u hiervan op de hoogte stellen. Druk op terug om terug te keren naar de hoofdpagina.

Stap 4: Transport volgen en afmetingen toevoegen

beeld

Terwijl het transport aan de gang is, begint het IoTproces in het aparte venster elke 15 seconden gesimuleerde temperatuurmetingen aan de zending toe te voegen. Kijk naar de uitvoer in het IoT-terminalvenster en het blockchain-venster om te controleren.

Voordat een meting in de blockchain wordt vastgelegd, wordt een hash van het meetgegevensrecord berekend en naar de smartcard verzonden. De smartcard gebruikt zijn privésleutel om de transactie te ondertekenen. Vervolgens wordt de handtekening toegevoegd aan de transactie en wordt de transactie vastgelegd in de blockchain.

Wanneer u in het browservenster op de gele verversknop drukt, ziet u de metingen in de grafiek verschijnen.

Stap 5: Voltooi het transport

beeld

Tot slot kan de ontvanger een eindstatus voor de zending selecteren en het transport afronden.

Stap 6: Slimme container resetten

beeld

Zodra de verzending is voltooid, kunt u het slimme pakket resetten. Nu wordt het resterende geld op de smart wallet-account teruggestuurd naar de kraan en wordt de account van de kaart gewist.

U kunt de kaart nu opnieuw gebruiken voor de volgende zending.

Technische diepe duik: kijken naar de code

Startpunt

Hieronder wordt de programmacode uit het originele Lisk Transport-voorbeeld getoond voor een transactie die wordt verwerkt met behulp van de Lisk SDK. Het maakt deel uit van de applicatie die op de sensormodule draait. Na het detecteren dat het pakket is geopend, slaat de sensormodule een nieuwe alarmtransactie op de blockchain op.

api.accounts.get({ address: packetCredentials.address
}).then(response1 => { let tx = new LightAlarmTransaction({ asset: { timestamp: new Date().getTime() / 1000 }, fee: transactions.utils.convertLSKToBeddows('0.01'), nonce: response1.data[0].nonce }); tx.sign(networkIdentifier, packetCredentials.passphrase); api.transactions.broadcast(tx.toJSON()).then(res => { console.log("transaction submitted"); }).catch(err => { console.dir(err); });
});

In dit codevoorbeeld wordt een nieuwe

LightAlarmTransaction

wordt gemaakt (#27), ondertekend met de tekenmethode van de transactie (#35) en vervolgens uitgezonden naar het netwerk (#37). Ondertekening wordt gedaan met behulp van een wachtwoordzin die is opgeslagen in het lokale geheugen.

In de transportdemo worden de

packetCredentials

account dat de transactie ondertekent, wordt aangemaakt met behulp van de client-app en vervolgens hardgecodeerd in de programmacode.

In onze versie van het project wordt het credential management overgedragen aan de smartcard. Dit maakt het sleutelbeheer veiliger en voegt een extra niveau van herkomst toe aan de gegevens die zijn vastgelegd in de blockchain.

Aangezien de smartcard een extern apparaat is, zijn enkele communicatiemiddelen vereist. In dit geval worden berichten naar de kaart verzonden via een NFC-radioverbinding. In dit bericht richten we ons op de blockchain-kant van de code, maar als je geïnteresseerd bent in de innerlijke werking van NFC-communicatie met behulp van een USB NFC-kaartlezer en de implementatie van de vereiste methoden van het tangem-protocol, kun je deze vinden in de submap tangem-smart. In de module tangemcard.js zijn drie belangrijke methoden geïmplementeerd:

  • createWallet

    : deze methode maakt een nieuw generiek portemonnee-account aan op de smartcard. De publieke sleutel van dit account wordt gebruikt om een ​​adres te genereren op de Lisk transport zijketen.

  • signData

    : deze methode wordt gebruikt om een ​​hash te ondertekenen of om een ​​pakket binaire gegevens te hashen en te ondertekenen met behulp van de persoonlijke sleutel die op de smartcard is opgeslagen.

  • purgeWallet

    : deze methode wist permanent het portefeuilleaccount dat op de smartcard is opgeslagen.

Een portemonnee maken op de smartcard

Voordat de smartcard kan worden gebruikt voor het ondertekenen van transacties, moet er een nieuwe portemonnee op de smartcard worden gemaakt en moet er geld naar deze portemonnee worden verzonden. Zodra dit is gebeurd, moet het adres voor de portemonnee worden geregistreerd als een geldig pakketaccount op de blockchain.

Het proces start (zie Stap 2: Zending aanmaken hierboven) wanneer de gebruiker een blanco smartcard (dus een smartcard zonder portemonnee) bij de NFC-lezer plaatst, de transportvoorwaarden invult en op de knop Aanmaken drukt. Dit veroorzaakt een functieaanroep op de

handlerRegisterSmartPackage

functie. De code voor deze functie is te vinden in het bestand handlers.js in de clientmap.


const handlerRegisterSmartPackage = (app, api) => async (req, res) => { // save current values app.locals.formdata.passphrasesender = req.body.passphrasesender; app.locals.formdata.passphraserecipient = req.body.passphraserecipient; app.locals.formdata.postage = req.body.postage; app.locals.formdata.security = req.body.security; app.locals.formdata.minTrust = req.body.minTrust; if(req.body.submit==='Fund Sender with 100 LSK') { // fund button pressed let participantAddress = getAddressForPassphrase(app.locals.formdata.passphrasesender); let success = await fundAddress(api, participantAddress, "100"); if(success) { doInfoMessage(res, `Fund sender ${participantAddress} with 100 LSK success`) } else { doErrorMessage(res, `Fund sender ${participantAddress} with 100 LSK failed`); } } else if(req.body.submit==='Fund carrier with 1500 LSK') { // fund button pressed let participantAddress = getAddressForPassphrase(app.locals.formdata.passphrasecarrier); let success = await fundAddress(api, participantAddress, "100"); if(success) { doInfoMessage(res, `Fund carrier ${participantAddress} with 100 LSK success`) } else { doErrorMessage(res, `Fund carrier ${participantAddress} with 100 LSK failed`); } } else { try { // // step 1 -> make sure that the card has no wallet if(haveCard && currentPacketId !== false) { doErrorMessage(res, "This card already has an address, finish the transport before using it again"); } const passphrasesender = app.locals.formdata.passphrasesender; const passphraserecipient = app.locals.formdata.passphraserecipient; const postage = app.locals.formdata.postage; const security = app.locals.formdata.security; const minTrust = app.locals.formdata.minTrust; let result1 = await createWalletUsingActiveCard() if(false===result1) { doErrorMessage(res, "Unable to create wallet on this card"); } let maxwait = 15; // max waittime in seconds do { if(currentPacketId===false) { await sleep(1000); maxwait--; } else { break; } } while(maxwait>0); console.log("got packetId %s", currentPacketId) let result = await fundAddress(api, currentPacketId, "100"); // enough for 1000 measurements @ 0.1 lsk each if(false===result) { doErrorMessage(res, `Funding failed for ${currentPacketId}, finish the transport before using it again`); } maxwait = 30; // max waittime in seconds do { let packetaccount = await getAccount(api, currentPacketId); if(false===packetaccount) { await sleep(1000); maxwait--; } else { break; } } while(maxwait>0); if(false===result) { doErrorMessage(res, "Timeout while waiting for completion of fund transaction"); } try { console.log("got senderpassphrase %s", passphrasesender) let senderAddress = getAddressForPassphrase(passphrasesender); const registerPackageTransaction = new RegisterPacketTransaction({ asset: { security: transactions.utils.convertLSKToBeddows(security), minTrust: Number(minTrust), postage: transactions.utils.convertLSKToBeddows(postage), packetId: currentPacketId, recipientId: getAddressForPassphrase(passphraserecipient), }, fee: transactions.utils.convertLSKToBeddows('0.1'), nonce: await getNonceForAddress(api, senderAddress) }); console.log("got transaction %o", registerPackageTransaction) registerPackageTransaction.sign(networkIdentifier,passphrasesender); let registerresult = await api.transactions.broadcast(registerPackageTransaction.toJSON()); doInfoMessage(res, 'package registration complete'); } catch(ex) { doErrorMessage(res, "Packet registration failed: " + JSON.stringify(ex.message, null, 2)); } } catch(ex) { doErrorMessage(res, "Packet registration failed: " + JSON.stringify(ex.message, null, 2)); } }
}

Het proces begint op regel #40. Een oproep naar

createWalletUsingActiveCard 

initialiseert een nieuwe portemonnee op de smartcard. Een wachtlus op regel #45 is vereist omdat het even duurt voordat de nieuwe portemonnee door de toepassing wordt gedetecteerd: variabel

currentPacketID

ontvangt het portefeuilleadres.

Een interessant stukje code dat hiermee te maken heeft, is te zien in het bestand handlers.js in de clientmap.

checkReader = () => { try { let reader = getReader(); if(false!==reader) { let activeCardData = getActivecardData() haveCard = true; currentPacketPublicKey = false; currentPacketId = false; if(activeCardData && "WalletPublicKey" in activeCardData) { currentPacketPublicKey = activeCardData.WalletPublicKey.toString('hex'); currentPacketId = cryptography.getAddressFromPublicKey(activeCardData.WalletPublicKey) } } else { haveCard = false; }; // console.log("hc %s / cpid %s", haveCard, currentPacketId); } catch(ex) { console.error("app.checkReader - error ", ex.message) } finally { setTimeout(checkReader, 1000); }
}

Deze

checkReader

functie wordt periodiek op de achtergrond aangeroepen met behulp van setTimeout. In deze functie wordt de NFC-kaartlezer gepold (lijn #5) en de

activeCardData

wordt opgehaald. Als er een portemonnee op de kaart aanwezig is, wordt de generieke openbare sleutel van de portemonnee omgezet naar een blockchain-adres met behulp van de

getAddressFromPublicKey

functie uit de Lisk SDK-cryptografiebibliotheek.

Het proces in de

handlerRegisterSmartPackage

functie gaat nu verder op regel #55 waar sommige fondsen naar de kaart worden gestuurd. Deze fondsen zijn vereist bij het indienen van transacties die zijn ondertekend door de portemonnee op de kaart naar de blockchain.

Nogmaals, er wordt een wachtlus ingevoerd (regel #61) die stopt totdat het account dat is gekoppeld aan de smartcard-portemonnee zich op de blockchain bevindt.

// client/functions.js #49 const getAccount = async (api, address) => { try { let accounts = await api.accounts.get({address}) if(accounts.data.length>0) { return accounts.data[0] } else return false; } catch(ex) { return false; }
}

De

getAccount

function (van functions.js#49) implementeert dit met een aanroep naar de Lisk SDK (regel #5).

Eindelijk, op regel #76 in de

handlerRegisterSmartPackage

functie, wordt een registerPackageTransaction geïnstantieerd en ondertekend door de pakketafzender (regel #93).

Na het uitzenden van deze transactie naar het blockchain-netwerk, is de pakketregistratie voltooid en bestaat de functie. Zodra de transactie is vastgelegd in de blockchain, bestaat er nu een geldige pakketrekening met initiële fondsen op de smartcard.

Meetgegevens ondertekenen

Na het starten van het transport (hier niet beschreven), begint de sensor met het verzamelen van gegevens en het vastleggen van deze gegevens aan de blockchain met behulp van a

register-measurement

aangepaste transactie op de zijketen. Om de herkomst van de gegevens te bewijzen, wordt elk pakket met meetgegevens ondertekend met de portemonnee op de smartcard.

Het belangrijkste deel van de

register-measurement

aangepaste transactie wordt hieronder weergegeven:

// transactions/register-measurement.js #27 applyAsset(store) { const errors = []; const packet = store.account.get(this.senderId); if (packet === undefined) { errors.push(new TransactionError("packet not found", this.id, "this.asset.id", this.asset.id, "An existing packet ID on recipient account")); } if(packet.status==='ongoing'||packet.status==='alarm') { let timestamp = dateToLiskEpochTimestamp(new Date()); if(false === "asset" in packet) { packet.asset = {} }; if(false === "measurements" in packet.asset) { packet.asset.measurements = [] }; packet.asset.transportstatus = 'active'; packet.asset.measurements.push({ timestamp: this.asset.timestamp, temperature: this.asset.temperature, humidity: this.asset.humidity }); store.account.set(packet.address, packet); } return errors; }

Terwijl het transport aan de gang is (regel #10) worden nieuwe (gesimuleerde) metingen opgeslagen in de metingenarray in de activastructuur van het pakket (regel #15). De klantapplicatie visualiseert deze metingen in een grafiek op de slimme pakketpagina, (zie hierboven bij Stap 4: Transport volgen en metingen toevoegen).

Een demonstratie van het gebruik van deze transactie is te vinden in de app temperature_and_humidity. Dit is code die in de sensormodule loopt en periodiek wordt aangeroepen om de transportomstandigheden te meten. Om in dit geval het principe te kunnen demonstreren zonder daadwerkelijke hardware, worden de metingen gesimuleerd. Dit is hieronder te zien:

// iot/temperature_and_humidity.js #30 const doMeasurements = async () => { let goFast = true; try { console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++") let reader = getReader(); if(reader) { await rescanActiveCard(); let activeCardData = getActivecardData() if(false===activeCardData) { console.log("no card in reader"); return; } if(undefined === activeCardData.WalletPublicKey) { console.log("not a valid smart package"); return; } let packetPublicKey = activeCardData.WalletPublicKey.toString('hex'); let packetID = cryptography.getAddressFromPublicKey(activeCardData.WalletPublicKey) let packetAccount = await getAccount(packetID); goFast = true; if(false===packetAccount) { console.log("packet with Id %s has not yet been registered", packetID); return; } else if ( packetAccount.asset.status !== 'ongoing'){ console.log("packet with Id %s - transport not active (status: %s)", packetID, packetAccount.asset.status); return; } else { // console.log("packet data: %o", packetAccount.asset); goFast = false; } // simulate gradual changes in temperature and humidity gSensorState.temperature += (gSensorState.temperatureUp ? 1 : -1) * Math.random(); if(gSensorState.temperature>30) { gSensorState.temperatureUp = false } else if(gSensorState.temperature<5) { gSensorState.temperatureUp = true } gSensorState.humidity += (gSensorState.humidityUp ? 1 : -1) * Math.random(); if(gSensorState.humidity>70) { gSensorState.humidityUp = false } else if(gSensorState.humidity<40) { gSensorState.humidityUp = true } let measurement = { timestamp: new Date().getTime() / 1000, temperature: Math.round(gSensorState.temperature*100)/100, humidity: Math.round(gSensorState.humidity*100)/100 }; // create measurement transaction let tx = new RegisterMeasurementTransaction({ networkIdentifier, senderPublicKey: packetPublicKey, asset: measurement, fee: transactions.utils.convertLSKToBeddows('0.01'), nonce: packetAccount.nonce }); // console.log("got transaction %o", tx) // console.log(tx.getBytes().toString('hex')); // sign transaction using on-card wallet const transactionWithNetworkIdentifierBytes = Buffer.concat([ cryptography.hexToBuffer(networkIdentifier), tx.getBytes() ]); // sign hash of data with the card const datatosign = cryptography.hash(transactionWithNetworkIdentifierBytes) console.log("got data to sign (%s bytes) %s", datatosign.length, datatosign.toString('hex')) tx.signatures = [await signDataUsingActiveCard(datatosign, false)]; if(false!==tx.signatures[0]) { console.log("sending transaction") // debug code: use verify function to check signature // console.log(tx.validate()); tx._id = transactions.utils.getId(tx.getBytes()); try { let res = await api.transactions.broadcast(tx.toJSON()); console.log("++++++++++++++++ API Response +++++++++++++++++"); console.log(res.data); console.log("++++++++++++++++ Transaction Payload +++++++++++++++++"); console.log(tx.stringify()); console.log("++++++++++++++++ End Script +++++++++++++++++"); } catch(ex) { console.error("broadcast transaction error %s", ex.errno) } } else { console.error("signing with card failed"); } } else { console.log('no active wallet') } } catch(ex) { console.error("doMeasurements error - %s", ex.message); } finally { setTimeout(doMeasurements, goFast? 1000: 15000); }
}

Zoals hierboven al geïllustreerd, worden de actieve smartcardgegevens opgehaald op regel #21. Temperatuurgegevens worden gegenereerd op lijn #38 en opgeslagen in een meetrecord op lijn #52. Volgende, een

RegisterMeasurementTransaction

wordt geïnstantieerd.

Nu beginnen de dingen anders te werken in vergelijking met het gebruik van een lokaal portemonnee-account.

Op regel #71 wordt de transactie geconverteerd naar een bytearray en wordt een prefix, bestaande uit de netwerkidentificatie, toegevoegd. De hash van deze array van bytes wordt berekend op regel #77 (met behulp van de hash-functie uit de cryptografiebibliotheek in de Lisk SDK).

Deze hash wordt naar de smartcard gestuurd om te ondertekenen met de

signDataUsingActiveCard

functie. De geretourneerde handtekening wordt toegevoegd aan de transactie (regel #79).

Ten slotte wordt een id voor de transactie berekend (regel #85) en wordt de transactie uitgezonden naar het blockchain-netwerk (regel #87).

De portemonnee op de smartcard wissen

Zodra het transport is voltooid, kan de portemonnee op de smartcard worden gewist, zodat de kaart kan worden gebruikt voor een nieuw transport. Dit gebeurt met een oproep aan de

purgeWallet

functie in de

tangemcard

bibliotheek zoals hieronder afgebeeld. Deze functie geeft goed weer hoe de communicatie met de smartcard onder de motorkap werkt:

# tangem-smart/tangemcard.js exports.purgeWallet = async ( reader, cid = 'BB03000000000004', pin1 = '000000', pin2 = '000',
) => { try { const pin1Hex = crypto .createHash('sha256') .update(Buffer.from(pin1)) .digest('hex'); const pin2Hex = crypto .createHash('sha256') .update(Buffer.from(pin2)) .digest('hex'); let tlv; let tlv1 = Buffer.from('0108' + cid, 'hex'); let tlv2 = Buffer.from('1020' + pin1Hex, 'hex'); let tlv3 = Buffer.from('1120' + pin2Hex, 'hex'); tlv = Buffer.concat([tlv1, tlv2, tlv3]); let base = Buffer.from([ 0x00, // Class 0xFC, // INS: Purge wallet command 0x00, // P1: 0x00, // P2 tlv.length, // Le: Full Length of UID ]); let request = Buffer.concat([base, tlv]); let response = await reader.transmit(request, 8192); // console.log("response %s", response.toString('hex')); let sw1 = response[response.length - 2] let sw2 = response[response.length - 1] let sw = 256 * sw1 + sw2; if(sw===0x9000) { // console.log("purgeWallet OK (%s)", sw.toString(16)) return decodeTLV(response); } else { console.error("purgeWallet ERROR (card response %s)", sw.toString(16)) return false; } return response; } catch(ex) { console.error("purgeWallet ERROR %s", ex.message) return false; }
};

Op regel #35 wordt een verzoek verzonden naar de smartcardlezer. Dit verzoek is een bytearray die is samengesteld door een aantal gegevensstructuren (regel #24 en regel #34) samen te voegen, zoals de kaart-ID (regel #21), twee gehashte pincodes (regel #22, 23) en commando gegevens (#26). Nadat de opdracht door de kaart is verwerkt, wordt de geretourneerde gegevensstructuur (antwoord, regel #35) gedecodeerd om te bepalen of het verzoek met succes is verwerkt.

In dit geval vertelt de opdrachtcode 0xFC (regel 28) de smartcard dat een opdracht voor het opschonen van de portemonnee wordt gevraagd.

Lisk-bouwers

Deze project is geïnitieerd door Caspar Roelofs die een Lisk Builders-subsidie ​​​​bemachtigde om het gebruik van smartcard-chips voor privésleutelbeheer in Lisk-blockchain-oplossingen mogelijk te maken. Als oprichter van Gimly Blockchain-projecten, helpt hij klanten om blockchain, IoT en andere nieuwe technologieën te gebruiken voor hun zakelijke behoeften.

Gimly gelooft dat zinvolle innovatie wordt bereikt door synergieën en maximaliseert samenwerking om voort te bouwen op de sterke punten van klanten, partners en de gemeenschap. Consultancy- en ontwikkelingsdiensten omvatten end-to-end productontwikkeling, oplossingsarchitectuur, technologie, product- en marktonderzoek, productbeheer en bedrijfsontwikkeling.

Marc Buma sloot zich aan bij het project als hoofdontwikkelaar, met zijn expertise in IoT, blockchain en JavaScript-ontwikkeling. Marc begon zijn carrière als R&D engineer bij Noldus Information Technology en werkte aan de ontwikkeling van geautomatiseerde gedragsmeetsystemen, en is sinds 2004 zelfstandig ondernemer (Bedrijfsnaam Bumos). Hij heeft gewerkt aan broadcast innovatieprojecten met Jetix, Disney, MTV, KPN en het Nederlands Instituut voor Beeld en Geluid, en heeft een solide achtergrond in het ontwikkelen van industriële krachtsystemen.

Momenteel ontwikkelt en onderhoudt hij op maat gemaakte producten voor gastvrijheid aan boord van luxe jachten, op blockchain gebaseerde gedecentraliseerde logistieke volgsystemen in de mode-industrie en VR-rondleidingen. Marc is actief als mentor/technisch adviseur voor verschillende startups en projecten op het gebied van blockchain en logistiek. Daarnaast is hij een fervent panoramafotograaf met een passie voor het behoud van cultureel erfgoed en auteur van een virtuele reisgids.

Werken met Tangem van Gimly

Als u geïnteresseerd bent om de technologie in uw eigen projecten te gebruiken, bezoek dan gimly.io om erachter te komen hoe u een proefpakket kunt verkrijgen, of informeer naar: business-to-business opties als u op zoek bent naar grotere hoeveelheden aangepaste kaarten, stickers of tags met een aangepast ontwerp en portemonnee voor uw cryptocurrency.

Disclaimer: deze blogpost is geschreven door onze communityleden, Caspar Roelofs (LinkedIn profiel) en Marc Buma (LinkedIn profiel) als onderdeel van hun deelname aan het Lisk Builders-programma.

by Lisk @Lisk. We bieden ontwikkelaars een softwareontwikkelingskit voor blockchaintoepassingen die in JavaScript zijn geschreven.Bezoek ons

Tags

Doe mee met Hacker Noon

Maak uw gratis account aan om uw persoonlijke leeservaring te ontgrendelen.

PlatoAi. Web3 opnieuw uitgevonden. Gegevensintelligentie versterkt.
Klik hier om toegang te krijgen.

Bron: https://hackernoon.com/how-smart-card-nfc-chips-improve-secure-key-management-in-blockchain-solutions-912×3722?source=rss

spot_img

Laatste intelligentie

spot_img