Dennis Lu
Erik Welsh
Comp 527 – Fall 2001
This document describes the design and implementation of our project. We set out to design and implement a secure smartcard-based electronic cash system. We ended up designing what we believe to be a not totally insecure smartcard-based electronic cash system and implementing a totally insecure smartcard-based electronic cash system.
The document is split up into sections describing the players and interactions in our simulated world of coke machines, smartcards, and banks. Each player and interaction has its own unique set of security concerns and goals. When I mention keys, they are all 1024 bits. When I mention signatures, I mean they are signed using the RSA keys with SHA1 message digests.
The code for this project can be found on owlnet in /home/welsh/comp527/project1.
- Each card is unique and cannot be duplicated
- Talk only to authorized banks and coke machines
- Sign each transaction made to ensure non-repudiation
- Prevent unauthorized tampering of balances and transaction records
- Record transactions accurately
- Card is physically secure.
The smartcard is initialized by the bank with a unique identification number, an Rsa Public/ CRT Private key pair for the card, an Rsa Public key for the bank, and a bank private key signature for the card’s public key. The bank remembers all the information it set on the card to enable future communication and verification with the card. The bank can also reset the keys later if it wants. The combination of the unique key and RSA key pair give the card its uniqueness. The data transmitted never gets very long and so we pad all data sent to and from the card to160 bytes using random data (we don’t have PKCS or other padding technology on the card). The private key is used to sign all transactions and communications to aid in non-repudiation. Transactions are stored in the card in memory and so are no accessible to anyone who can gain read access to the card. The card has several modes of operation. Before it is initialized, many methods are disabled. After being initialized the card can be in modes talking to the bank, a coke machine, or neither. Depending on which mode it is in, methods are made available to the bank, coke machine, or neither respectively. The details on how the modes and keys and stuff are used are discussed in the sections dealing with communicating with the other objects.
The object on the card is called TheWallet. Its AID is 0x999999999999. We do not have any keys or anything stored or used on the card. We implemented a very simple and non-secure system using random shorts as a kind of authentication system (we would use longs or something bigger, but the card cannot handle numbers larger than 16-bits). The card has a unique identifier and a random number associated with it. The random number is used in communication with the bank. Assuming the bank is the only entity that knows about the card’s random number and id. Transactions are stored in a static short[] since encapsulating objects is considered a bad practice. In fact, there are no local variables at all. All variables are private fields. There is a maximum of 100 transactions that can be stored on the card before it must be downloaded and reset by the bank. The balance is kept as a short so you can’t have too much money on the card either.
- Easy-to-use graphical interface
- Each coke machine is uniquely registered with a bank
- Sign each transaction to ensure non-repudiation
- Prevent unauthorized cards, or cards with insufficient funds from purchasing a soda
- Record transactions accurately
- Communications channel with the bank is completely secure
The coke machine is given authorization codes from the bank which include:
- Unique coke machine id which is registered with the bank
- Public and Private Key for use in transactions
- A signed public Key by the bank to prove the coke machine was authorized by the bank
The coke machine will have a display for the current balance of the card which will re-initialize to zero on the removal of the smartcard. There will be buttons associated with different flavors of soda which will require you to first have a card inserted into the card reader; second, require that the card be authorized by the bank; and third, require that there be enough money in the balance of the card to completely pay for the transaction. Upon completion of a transaction, the coke machine will not accept any more requested until the card has been removed and re-inserted. This would be ideal if the reader were a card swipe, but this ensures that a user cannot try to purchase more than one soda without making sure that s/he has gone through the proper authentication process. The coke machine will also keep track of all information that occurs in the transaction between itself and the smartcard so that it has a record of the transaction to send back to the bank to ensure payment for the vended soda.
The implementation of the coke machine followed the design closely. However, we were not able to implement the higher security features such as the use of public/private keys and the signed key from the bank. The implementation is flexible enough to accommodate the addition of such security without re-designing any of the user interface. By using the MVC pattern, one would only need to modify the model portion of the coke machine to gain the added security.
- Keep track of all transactions both coke machine and smartcard
- Authorize coke machines and smartcards so that they can perform transactions.
- Verify the transactions on any account to ensure that no one is being cheated out of any money
- Display a complete report of the transactions of a smartcard
- Securely talk to a smartcard to either read its transactions or add money to its balance
- Communicate with a coke machine to obtain a record of its transactions
The bank has one of the toughest jobs because it needs to be able to verify all the transactions between coke machines and smartcards. To this end, the bank first gives each smartcard and each coke machine a unique id so that all transactions by the devices can be monitored. The bank also is able to give out public and private keys to both the coke machines and the smartcards so that the two will be able to have an encrypted transaction and guard against either being susceptible to man-in-the-middle attacks. Finally, the bank also gives out public keys which it has signed so that coke machines and smartcards can use those for authentication purposes. The bank has to have a robust engine to look for double charging by both smartcards and coke machines. It must also be able to display all the transactions of the smartcard so that a user can repudiate any of the charges that s/he sees.
Unfortunately, this was the least implemented part of our project. We were able to establish a connection with both the coke machine, through the use of files, and the smartcard, through the card reader. However, we did not have enough time to fully implement a system so that users could repudiate their charges or that the bank itself could verify the transaction records it was receiving. With a little more time, this functionality could be implemented in the bank model along with the higher-level security functions that the card did not support.
- Prevent replay attacks
- Communication with authorized coke machines only
- Session integrity
- Freshness
- Prevent overcharging
- Coke only deals with legit cards
- Prevent man in middle
- The coke machine or card may not be authorized
- Both the coke machine or card may be evil
The card-coke machine interaction proceeds as follows:
- The first thing that happens when the card is inserted is that the coke machine makes a quick handshake with the card. This puts the card into the coke transaction mode.
- The coke machine then sends over its public key and bank signature of the public key.
- The card verifies the signature of the public key. If it passes, it then returns its own public key and signature to the coke machine.
- The coke machine verifies the key. This verification of signed keys gives us authentication that both the card and the coke machine have been initialized by the bank.
- The coke machine sends to the card the coke machine’s ID, its current transaction number, the amount it will charge, and a random number. This random number is used to give an extra bit of uniqueness to each transaction and make it harder for evil coke machines and cards to fake transactions. It can be considered a nonce. This number should be a long or bigger if possible. This data is put into the data array, padded, signed, and then encrypted and sent to the card.
- The card decrypts the data and verifies the signature. In response, the card sends back, the card’s ID, current transaction ID, balance, a boolean indicating that it has more space for transactions, the random number sent by the coke machine, and its own random number for the current transaction. Before sending, the data is padded, signed, and encrypted.
- The coke machine now waits for the user to pick a drink. When the use picks a drink, the coke machine sends all the data relevant to the transaction to the card. This includes the coke machine’s id, random numbers and so on. This is of course padded, signed and encrypted.
- The card stores the signature sent with the transaction and stores the data of the transaction. It then signs the data and sends it back as a confirmation of the transaction. The card also puts itself out of a coke machine transaction mode.
- The coke machine stores the data and signature and then asks for the new balance and displays it.
This protocol is designed with the goals and objectives in mind. To prevent replay attacks the card ends a transaction after one successful one. The only way to get the card to accept another transaction is to pull the card out and reinsert it. So, a user cannot buy multiple sodas with one insertion of the card. The signatures of the public keys of the card and coke machine by the bank act as the authentication scheme that something has been initialized by the bank. Session integrity is maintained by the transaction IDs and the random numbers unique to each transaction. If a card is removed and put into another reader, the numbers change. So a user cannot swap cards out. Overcharging is prevented by constantly exchanging the amount that will be debited. Also coke machines have to register their prices with the bank. The man in the middle will not be able to get much information from the traffic sent between the card and coke machine since it is always encrypted and signed by each party.
Once again, we have no encryption going on. We were however able to implement the protocol sans encryption and signatures. The communication between the card and coke machine is done using a CokeCardBroker object, which is essentially a layer of abstraction to between the two entities. The object is also declared final so no one can extend it and gain the functionality that a coke machine can have with regards to the card. The interaction with the coke machine and card is just about completely working and tested.
- Only talk to initial bank
- Only bank can add money
- Only bank can access transaction information
- Prevent man in middle
- The initial interaction is completely secure
The card-bank interaction proceeds as follows:
- The user inserts the card
- The bank handshakes the card by asking the card if it is initialized. This puts the card into bank communication mode.
- If the card replies that it was not initialized, the bank generates a new id, new public and private keys and a signature for the public key. The bank sends this and also the bank’s public key to the card in a series of transactions. When all this information is set, the card is told to be in an initialized state. From now on, communication from the bank needs to be encrypted except for the initial handshake.
- The bank has to remember all the information put onto the card. Since it has the ability to reset the keys and stuff in the future.
- The user has the ability to control what they want to do with the card at this point. They have the ability to add or set the card’s balance or retrieve the set of transactions on the card or whatever. All communication to the card at this point is signed by the bank and encrypted by the card and bank respectively.
This protocol attempts to prevent the kinds of attacks that might happen when a smart card talks to the bank. The encryption and signatures help ensure that only a real bank and real card can talk to each other and that no person in the middle can interfere.
There is no encryption or signatures going on here either. The bank talks to the card though the BankCardBroker object. This object is also final so no one can subclass it to gain functionality of a bank. Most of the other protocol and features are implemented. We have the ability transfer and retrieve data to and from the card and bank.
- Design an easy-to-implement method of transferring data between two programs
- Keep persistent data (i.e. you save information even when the program exits)
- The connection between the coke machines and banks is secure in all aspects
Since this was a strictly internal format for communication between coke machines and banks over a channel that was guaranteed to be secure, we built this communication protocol around XML. The main reason for this was the ease of parsing XML with the native Java objects such as StreamTokenizer. Also, the parsers could be hard coded around a particular set of tags since the format is internal and will more than likely never change. The protocol was such:
- Within the bank’s user interface, a user would select to “Authorize a Coke Machine.”
- The bank would then ask how much the coke machine would charge for its merchandise
- After the user input the price of the soda, the user would then select a file name to which the file would be saved.
- Once the file was saved in a mutually accessible location, a user at the coke machine would select to get the authorization codes from the bank. Otherwise, the coke machine would not be able to communicate with the smartcards.
- The user would then select the file that was written by the bank.
- The coke machine then parses the file and sets the appropriate fields.
On the other side, when the coke machine needed to transmit all of its transaction data to the bank, the protocol was very similar. The only real difference is that the coke machine writes the file to disk and the bank then reads the data in for processing.
Since the channel was given to be secure, this protocol was straightforward to both design and to implement. The parsers are hard coded and will error if they do not receive a file with the given format.
The implemented format of the authorization file was:
<authorization>
<machineID>”An ID”</machineID>
<transactAmt>”Amount in cents”</transactAmt>
<encryptKey>”Encryption Key as an array of
bytes”</encryptKey>
</authorization>
The implemented format of the transaction file was:
<transaction>
<cokeID>”An ID”</cokeID>
<cardID>”An ID”</cardID>
<cokeTransID>”A Transaction Number”</cokeTransID>
<cardTransID>”A Transaction Number”</cardTransID>
<charge>”Charge in cents”</charge>
<cokeRandom>”Random Nonce”</cokeRandom>
<cardRandom>”Random Nonce”</cardRandom>
</transaction>
We started this project with grand expectations and ended with grand headaches. In general we were not able to implement any of the goals for this project when it came to anything regarding encryption. Schumberger should go back to drilling for oil. We would like to patent a new design pattern for smart cards. We call it the Monolithic design pattern. It is named after how “good practice” on the smart card is to not use objects, methods, local variables, or garbage collection. This is the worse project we have ever submitted. However, we will gladly personally demonstrate how much of it does actually work.
This document was finished on time with the following timestamp: (long)1000987533028.