 Welcome to the presentation, Central Bank Digital Currency Threats and Vulnerabilities. We will start with a background, then we move over to a detailed system description of the prototype, system components, and the point-out functions that need protection, information to secure, and secure communication. Then we will detail vulnerabilities that were found in the retail Central Bank Digital Currency prototype for Phase 1, and then I have to talk about everything else that needs to be handled before going to production, and we will end with a short description of the solutions and an even shorter summary. There will be lots of slides and lots of information, and I have to talk really, really fast. Don't forget to note down interesting slides. If you want to go back and actually understand what I have said. Where to start? My name is Ina Vitek. I'm born in Stockholm, Sweden, and I'm starting the penetration test in 1996. I moved from being a consultant to work at a big retail banking company in Sweden, and started with a computer emergency response team, and after a couple of years I moved into information security. I've been working at the risk bank for eight years, but the last two with the Central Bank Digital Currency. My interests are web application security, network-related tool, I'm a writer of Mac-off. I love party tricks like DMA attacks and look at pin-by-pass attacks and other attacks you can do at the bar counter. I also attended DEF CON many years. My first DEF CON was DEF CON 6, and I've been a speaker and helped out at DEF CON with other things during the years. The Central Bank of Sweden, side six bank, is a very small central bank, it's just maybe 350 employees. I have also a small disclaimer, the views and opinions expressed in the presentation are mine, and do not necessarily represent the views and opinions of the risk bank. The E-Krona project. Why Central Bank Digital Currency? I will not talk about the politics here, but I have to mention that the physical cash in Sweden has been declining. Commercial banks have a very good and widespread digital ID and also a payment service called SWISH. SWISH is connected to one of your bank accounts, so it's very easy to do person-to-person transfers. And now we also can do payments in stores. In Sweden most of the transfers are bank transfers, card payments or SWISH transfers. The Central Bank of Sweden thinks that should be a digital alternative to physical cash. The E-Krona project started at the risk bank, and we wanted to run a pilot to see how Central Bank Digital Currency should work. So we first started with the procurement, we had some requirements of course, we didn't have requirements of the technology that should be used, but we had security requirements, functional requirements like user stories and non-functional requirements. Another winning company, and the winning company has developed their prototype, and I will talk about that prototype of phase one, the year one. We are still working on the prototype, but we call it now phase two, that this presentation is only focused on the phase one prototype. The goal of this presentation is to share insights and of the security challenges of building a prototype of a two-tier retail Central Bank deep concurrency based on blockchain and value-based tokens. We will now go into the detailed system description of the prototype. The prototype in phase one is a blockchain with value-based tokens in a two-tier model. So we have a user, we have an app, in the app there are logic of course, and we have stored information in the payment instrument. The payment instrument could be like a mobile phone, but we have also developed a payment card, a smart card that can handle these payments. The logic in the app is that it needs to be secure. For example, a pin handling, signing the transaction encryption, and on the disk of the application we store of course the pin verification, the pin you can call just pin. Private keys for the tokens, authentication keys, and message keys. So we have lots of things in the app and on the mobile or payment device, payment instrument that needs protection. But we're not talking about anything about the tax against the user or user interface. And the app will connect to the payment service provider's business logic. So the arrows here in the presentation is that the arrows also have to need some type of protection of course. So in the payment service provider's business logic, we have authentication push messages, like firebase. If you want any limits like how big transfers could be or how many transfers you can do, this is limits in the business logic. And we have lots of back office functions here. And this is stored in database and also the disk of course, but I just write the database here. So we need a storage of authentication keys, payment history, customer data, message keys and so on somewhere. And all these functions and information needs protection. But the business logic communicates with the payment service provider's core download. And the core download handles the security and logic of token transactions, token verification and wallet management. And the database of the core download, the payment service provider's core download, they of course need to have the user public keys, wallets, tokens, back chain. And we'll come back to what back chain is and lots of certificates. But you can't do anything if you don't have any money or tokens in this case. So Rick's Bank also has a core download. And the security logic here is issue and redeem, token verification and core network management. The information is handled on that core download. So we have to secure the public keys and back chain and certificates. But when doing a transaction, the consensus mechanism of the core download is a core downloader. So this is a consensus method mechanism in the prototype of phase one. And if you're doing a transaction, you have to check for doubles fans. So the core downloader prevents doubles fans and it also signs that transaction. To that core download, we have a database where we have keys and certificates. But we have also the hashes of tokens. These are the hashes, these are the tokens that are spent, information about spent tokens. So if you can remove tokens from this database, you can spend tokens once more and do doubles fans. So it's very important that it's secure. But the Rick's Bank also has business logic. We have lots of back office functions and we want to be able to pay interest for the money in circulation. And we also have information about the outstanding central bank deal currency that's in circulation. We also have connections to the Rick's Bank real-time gross settlement system. This is an RTG system that most central banks have. But we're not talking about that because that has nothing to do about the threat and vulnerabilities of this prototype. But to be able to pay, I know that technicians love public keys. But normal users, we want some similar way to do payments like a phone number or email address or alias or something. So we have an alias database and that handles adding mobile alias to a payment service provider and wallet. And these alias and wallets are stored in the database. And this is also a critical part of the solution because you can imagine what happens if you change that all alias is pointed to your wallet. So of course it has to be secured also. But we also have lots of other payment service providers in our prototype. So we can do payment service provider to payment service provider payments. So what is backchain and how to exploit bad implementation? So to explain this in a very simple way, the Rick's Bank coordinate. So we have a coordinate at the Rick's Bank. And if payment service provider needs tokens, money, it asks for an issue and Rick's Bank makes that issue. So this is how it looks in a very simple way. So from nothing, the Corda starts with a transaction. The actual transaction number here is a very long binary number. But I just write one here as an example to simplify it. And in that transaction we have one token. And the token, the name of the token is the transaction ID and the index of the token. So this is the first token in transaction number one. The amount is 1,000, the owner is payment service provider one. And the Rick's Bank has signed this transaction as a new reference. It's from dinner. Then maybe user A wants to withdraw 200. Then there is something called token selection. So Corda will look for a token or tokens that has 200. So we find this token and locks it. Since no one else can touch this token during this process. Then Corda creates another transaction in this example number two and creates one output token here. So this token is called two. And this is the first token of the transaction two. It's a 200. And it's signed by user A. So this is the public key for user A here. And it's signed by payment service provider one. And this has a reference. So this token rise from this token. The first token of transaction one. But we have changed here also. User A gets 200. But the payment service provider actually creates its own change of 800. And then it's called, that token is called, it's a second token in transaction two. And its owner is PSP1 and the sign is signed by PSP1. And it also has the same reference points to that transaction. And then everything is done. The first token here is marked as spent. You can't use that anymore. And then maybe one day user A want to make a transfer to user B at PSP2. So user A wants to send user B 50. So the token selection here looks for a token owned by user A that could handle this transaction. So it finds it, locks it, creates another transaction, makes one output token. And also the change to user A. This is sent to payment service provider two. So payment service provider two also get these tokens. So payment service provider two to verify the authenticity to see that this is valid. The payment, the coordinate of payment service provider two must verify it by looking at all earlier transactions. But it has only that transaction three. So payment service provider two coordinate will ask for all earlier transaction leading up to this transaction. It will ask payment service provider one for the back chain here. So payment service provider two can verify the references here. So it points back to this transaction to points out to this transaction. And this is the issue. And then we have the whole back chain from the issuing to the transaction number three. And now the payment, the coordinate of payment service provider two can verify all the signatures and see that the chain is not broken. This is very important and I will come back to this later. And the prototype for phase one was built on Corda 4.5. And it corresponds corresponding token SDK. And most of the information is very simplified, of course, and the banks in the prototype in the design, I have verified them in the Corda 4.7 also. And so how to exploit token selection and long back chains. So what can a user do if they want to mess things up? They can withdraw three and deposit two. So this is a start. So when a user want to withdraw three, it will take 200 from the PSP1 and PSP1 will create change. So it receives a token of 197, but user A will receive a token of three. Then it wants to deposit two. If we look for a token that can be deposited or used for depositing and we'll find this token three and create a new token of one that change back to user A and a token of two. So the money goes back to PSP1 to go back to PSP1. To make things a little bit clearer how this work, I will clean this up a little bit. So I know all the historic transactions to the left and adjust all the tokens. And so what A does is he does this over and over again. So we withdraw three, so now it's 904 and then he deposit two and he gets that and it's moved over. And you can do this many, many, many times. You get many tokens, many historic tokens and in the end the user A deposits all these tokens. So all the tokens that you have or hundreds of them are deposited to PSP1. And now PSP1 have all the historic tokens and all the tokens that are still valid, not spent. But sometime in the future, maybe the administrator of payment service provider one want to redeem and move it back to the Riksbank. Tell the tokens back to Riksbank to get the Swedish crooner instead. And what happens is that all the tokens is moved over to the Riksbank corner node. And the Riksbank corner node wants to validate the tokens. And to do so it needs the history and the back chain actually of all the tokens that are redeemed. And this will draw lots of resources on the Riksbank corner node. And the Riksbank corner can actually crash if it's not set up or the system is not designed correctly. I will go into the consequence a little bit later but I want to describe there are other setups that gives better effect. So if you're using several issued tokens you also can start with several, you will get several miracle trees. This is a simple way of describing it. It's like payment service provider one has three issued tokens. Payment service provider one has done one issue of 1,500, one issue of 2,000 and one issue of 3,000. And user A does a withdrawal of 100 with for some time and make another issue, make another withdrawal. Maybe it will get a token from another issued token. And then the user splits up his tokens to several. Maybe he has a friend, user B, user A sends lots of small transactions to user B. And that will split up his tokens to very many small parts. And then user B sends them back to user A, but in one big chunk. So now we are getting a very complex back chain. And if user A does this over and over again. So we also have lots of tokens and very long back chain where you get the transaction of death. And what can we do with the transaction of death? It can permanently lock tokens because when you're sending transaction of death to someone. It may crash and call downloads. And sometimes crashes give inconsistencies. So if user A want to transfer 5, this transaction of death. The 5 here is a transaction with many tokens and very long back chain. And it sends it to user C to a payment service provider that has not seen any of these tokens or back chains before. Somewhere in this process, someone will have to send it to the Riksbank Corda node. Please mark this transaction or token as used. But when doing this transaction of death. I am able to crash both payment service provider 1, the one payment service provider I'm standing from. But also the receiving party. Both nodes can crash. One can crash, two can crash. It depends on the setup resources and so on the design. But when this crash happens, it also can happen before the Corda nodes actually mark them as spent. So in this, in the test I have done, the Corda, the Riksbank Corda node query marked this transaction as used. This token is used. But this token is available for the payment service provider. So user A can't use his wallet anymore because you look at your wallet. You see the amount, the balance is just like 100. But when you try to transfer them, the Corda node will say some of them that the tokens in this transaction are marked as used. And therefore you can't make any and the transfer from this wallet. The wallet is permanently disabled or it's not functioning anymore as you want it. And it has to be, you have to solve the inconsistencies of this somehow. There are other design weaknesses that you have to look out for. It's network problems, timeouts in memory token selection and locked tokens until restarted. So payments in the prototype phase one is a signed transaction on the smart card traveling through the payment service provider of the merchant to the card holder payment service provider. And then the transaction is going back from payment service provider three to payment service provider one in this example. So what I did in the prototype for phase one, but I did card payments every second or so as fast as I could. I did small card payments. And when I'm doing these card payments, payment service provider one will communicate with the Rick's Bank Corda node to mark to say that these tokens used in the card payments is spent. But when I'm doing these card payments, I just killed the corda notary princess. But I'm, but still when the princess corda notary is down, I still continue to doing card payments. So now hours start to happen. And so payment service provider one will get timeouts and will send errors back to payment service provider three. And they will say some of the tokens you are using has not been spent because you have timeouts. But when I start off the Rick's Bank Corda notary, I still continue to do card payments. And somewhere here it gets mixed up. So some of the transaction will be marked as used, but in memory of the payment service provider three, the tokens are still marked as available. This is very easy to fix. We just restart the PSP3 corda node and the tokens will get updated in the correct way and marked as spent here also at the payment service provider three. But these are very complex processes and you have to be sure that the right tokens are marked spent where and when you should do that to be able to not have these type of weaknesses in the system. And there were some people at ING that found out that also an even payment service provider can lock tokens that other payment service providers has. So in this example, user A want to send five to user C at payment service provider three. Normal transaction. So A sends tokens to payment service to user C at payment service provider three. And that payment service provider three will mark that token as spent. So the token in this transaction is spent and it's marked in the Rick's bank corda notary. Everything is fine. But so the token two is available, of course, and the token one was spent in the transaction. Everything is fine. But as you are the evil payment service provider here, you actually have information about token number two. You can send a transaction to the Rick's bank corda notary node to say, well, token two is also spent. Now token two is spent and the user C can't use his token anymore because the Rick's bank notary node has marked it as spent. This is how the setup for the prototype for the Rick's bank phase one is done. It's a non-validating notary node. It can be sold by changing to a validating notary node. And then you can't do this attack anymore. So we have to take this into account too. I also have an ending note on token selection. If a payment service provider want to make a redeem, in this example the payment service provider one has three tokens in his vault. One token of two million, one token of one million, another token of one million. So the administrator want to make a redeem of three and a half million. But if a user just milliseconds before want to make a withdraw of 50, the corda will start doing that by locking one of the tokens. And corda will tell the administrator, well, you don't have 3.5 million right now because you only have three million available. You have to try again later that the user A will get his 50. This is not a big problem if he just has one user. But if you have millions of users that always is trying to withdraw, it will be very hard to do some of the back office functions. You have to have a design that can handle this. It just was a parenthesis of the challenges that we have had. Now we move over to privacy problems. So as we talked about before about the back chain, to be able to verify the authenticity of all of the tokens, all historic transactions for that token is needed. For PSP to verify this token, it needs all the historic transactions. So PSP2 can see how PSP1 have done one issue and how user A withdrawn 200 for paying this token to a user on PSP2. But older and longer back chains reveals more. So what can an administrator of PSP2 see? Not if that PSP2 get one transaction of 60 to verify the authenticity of this token. It needs all the historic transactions deriving up to this token. So where does this 60 come from? So the color of this payment administrator 2 will get the back chain to see that user G from PSP1 has sent a token of 50 to user A. And user C from PSP3 has sent a token of 22. So this 60 contains, doesn't matter, 20 from this token and 40 from this token or maybe 50 from this token and 10 from this token. Doesn't matter, but both of these tokens were used in this transaction here. But where does these tokens come from? So the corridor will go out on the corridor network and get all the back chain. And the back chain is all the transaction deriving to this token. And it needs to go back to the issuing. So it will continue going back and back. So you will see that the token of 50 comes from another token of 50 that comes from a transaction of 325. And that user 365 comes from three other tokens. So then we come back to the issuing here. So when we have the whole chain back to the issuing, we have all the transaction leading up to this token. Now the corridor network can verify the authenticity of the token by verifying all the signatures. See that the chain is not broken. But the administrator of payment service provider 2 can also go into the corridor node to see all these historic transactions. So this more practically have written some small scripts to be able to visualize the back chain and the historic transactions. So in this practical example, I'm running the corridor of PSP 2 and I'm an administrator of payment service provider 2. And with only information from the payment service provider 2 corridor node and the business layer of payment service provider 2, I'd be able to get the back chain and visualize it. And I will practically show you how this is done. So what we have to do is extract the back chain, get all the transactions in the back chain, maybe do some data mining and then visualize it. So this is how you should do that. So to get the back chain, you log into the PSP 2 corridor node and in the corridor process also has a corridor shell. So you log into the PSP 2 corridor node and start the corridor node shell. And then you run the command internal verified transaction snapshot. When running this command, corridor will output all verified transactions. All transactions it knows about and also about all the back chain transactions. It's just a mess, but I just, for example, points out one transaction here. This is how one transaction from that command looks like. We have the transaction ID first, transaction ID. We have also the signer of this transaction. We know who is a payer here. This is the front address. And here are the inputs of this transaction. And this shows the tokens from the input. It can be one or more tokens. And the naming here is this is an old transaction. And this is a token. The first token in this old transaction was the input token for this transaction. And then we have output tokens. The first output tokens is always a payee who gets the transaction. This is the public key of the payee. And here we can see the amount. If there are a second output, it is a change that the owner of the token gets back. You can see the public key of the change is the same as the signer of that transaction. What we do now is just write a small script that takes out the payer from the token and who is the payee receiving the amount. That's all what we need. But I also take out if there are any inputs. If there are new inputs in this transaction, I know it's a transaction from the Wix Bank. Because the Wix Bank is the only one that can issue transactions. When you issue transactions there are new input tokens. I can also look at the public key. If the public key is a couple of bytes shorter, in our prototype for Phase 1, it's a payment service provider. So users have a little bit longer keys. So now we can see who's the Wix Bank, who's the payment service providers, and what's users. So I just extract all those transactions and create a JSON file. It just says from this public key to this public key and the amount. Just thousands of transactions in the JSON file. And that's all we need right now. But you maybe want to have wallet IDs. And wallet IDs can be found in the business layer of the... In the business layer of the payment service provider too. So if you have an app, you want to go through the transaction history, your historic transactions. And that's stored in the business layer. The administrator of the payment service provider too can go in and look there. So this is the user history record extract from the payment to business layer. So here we have the transaction ID. And actually that's the same transaction ID that was in the back chain. So here we can map the payer and payee wallet ID. But there are other ways to do it also. Because if one of my users has received a payment or sent a payment to someone, I have their wallet ID in my transaction history, of course. And then in Corda you always can look up the public key for a wallet. If I just look at my transaction history, there are lots of wallet IDs, and I can just look up all the public addresses I know of, and then map them or enrich the JSON file. And then I'll enrich JSON file and just pour that into an HTML file. And with the D3.js, the data-driven documents library called D3.js, I use a function called D3.js. And they just connect all those arrows, all those transactions from A to B, B to C automatically. So in HTML file I just say, I just point at the JSON file where I have the enriched transactions. I set up the graph with the arrows and just print it. And it would look like this. And so this is how the web page looks like. So here I can detect the Rix bank. And I can see one of the historic transactions to a payment service provider. So this is an issue. So this payment service provider has done an issue of one million. And from that one million, one user called this wallet ID on PSP1 has withdrawn 1,337.10. So then I know this payment service provider is payment service provider one. And this payment service provider from this wallet has done a transaction to see if I can get hold of it now. So this payment service provider three. And there has been two transactions to this payment service provider, the wallet on this payment service provider three. And it's one transaction of 1,337.40 and 1,337.50. Then it comes to my payment service provider two here. To my user here at payment service provider two. But when I received this payment of 1,337.60, I also get the old historic backchains. So I can now see all the historic transaction leading up to this. And yeah, so backchain privacy. First I have to say, even if you don't have the wallet ID, you have the public key. And public keys are probably also personally identified about the information. And whichever technology you choose, you have to take this into account. And for some blockchain technologies, this can be a challenge. So we have to fix this in phase two. Then we have everything else. Everything else that I have not talked about this presentation. And everything else that has to be solved before going into production in a token-based retail-central-bactical currency. So we have performance and the verification of the tokens. We have to solve, if you have lots of lots of tokens, or very long backchains. It doesn't matter what technology you are using. You have to verify the authenticity and have the performance. And we have also a challenge with the high availability and in-memory token selection. So all the token selection is done in the memory of the corda node. So how should you do 24-7 service like if you're going to upgrade corda or operating system? You can't just shut down the corda node and disable payments during this time. And how should you do resource recovery after catastrophic failures? You can't just take a database backup and restore it because you are missing all the transactions leading up to that catastrophic failure. So you need some kind of area of storage where you store all the transactions so you can build up or some other ways to fix the inconsistency when restoring a corda node. And then secure offline. Can that be done? We have to look at it when we will look at it. We have problems with non-repudiation, meaning more or less authentic authorization. You have to be sure it is the right person that has done the transaction and it has to be proof that this user has done this transaction. And then we can't miss anything regarding information security like access control, operational security, internet management, fraud detection, AML, neural customer. We have all the IT security to solve or has to be in place before going in production and of course compliance, laws, regulations, financial compliance. And there are lots of solutions. There are many solutions for the presented challenges. I haven't talked about lots of challenges, but there are lots of solutions. I will not go into the solutions in this presentation. There are chain-snipping, shipping, key-rotation, serial knowledge proof and other encryption to solve some things. And we have validating nuclear nodes to solve other things. We have hardware wallets. Maybe we could work with offline and restore procedures and functions for correcting inconsistencies. Maybe we can fix everything. It's a technical project and we probably can solve it technically. And Rick's thing is now experimenting with other designs and we'll also look at other technologies. But I also have to say that every solution will have their own consequences. So if we just solve one thing, maybe we'll have other problems like performance or other things. I also want to say that during phase one, we had a design where the private key was on the payment instrument, but the tokens were on the core nodes. So to experiment with the payment service directory 2, we are trying to have both the key and the tokens on the payment service provider. And we're also looking for offline functionality and then we will experiment with having the key and the tokens on the payment instrument. So we can do the transfer of tokens offline to another payment instrument device. So we are looking at lots of other fun things during phase two and we are not ready for conduction any time yet. And we probably have to change the laws of the central bank in Sweden, the Riksbank law before moving to production anyway. So we will still looking at the central bank due currency and other technologies. So the summary, the goal of this presentation is to share insights of the security challenge of building a prototype of the two-tier retail central bank due currency based on a blockchain with value-based tokens. I have only presented threats, vulnerabilities and security phase as some unknowns. I have not presented all the good design and all the positive lessons learned. That's another presentation. We have invented and built so much good working parts, components, solution design, and we have learned so much when we are now moving forward and we look how we should build a system that could be run in production in Sweden. But I am not talking about that in this presentation. That's the bad stuff, okay? Thank you for attending.