Last updated at 8:17 pm UTC on 23 January 2009
KryptOn is an object-oriented Cryptography facade designed to facilitate straight-forward augmentation of any program with common, easy-to-use authentication, authorization, and encryption services.
These functions operate between two parties:
- a user uses a system securely
- two associates converse privately
- two programs communicate
KryptOn tries to take advantage of security sense already commonly understood by key bearers. Accessing digital information with KryptOn is via a physical flash-drive "key" on your personal keychain. Other than requiring a password to occasionally decode this key file, passwords are otherwise absent from KryptOn-based systems.
Why a physical-key based system?
1) Better security. Common, password-only systems put user-convenience at odds with security. Users will choose easy-to-guess passwords, and sometimes even password sharing occurs. KryptOn is convenient and natural to use properly, and inconvenient to use improperly.
2) Better identity. Id/password systems don't always allow people to be represented by names they wish to be called because, in many cases, the Id is also the identity. For example, you can't have the userId "mike" in most public systems today because its already taken. In KryptOn, to borrow a phrase from Craig Latta, "name and identity are distinct", so everyone can use whatever name they want. Although KryptOn itself doesn't need them, built-in uuid's are available to assist humans reconcile ambiguous "mikes" if necessary.
3) Better usability. If you need to get up momentarily, don't have to "logout" to protect access secure digital information; just don't leave your keys sitting there where someone else may steal them. All KryptOn objects are flushed (overwritten in memory) within seconds, rendering the system secure.
From the ground up, the primitives of KryptOn are exact implementations of this book
by Nils Ferguson and Bruce Schneier.
|Primitive or specification||Pages||Notes|
|AES (Rijndael)|| |
|Fortuna|| chapter 10 || Generator only |
|Secure Channel|| chapter 8 |
|Key exchange|| chapter 15 |
To use KryptOn, your programs only ever use (i.e., send messages to) just one of two classes: MakoAgent and MakoNode. However, you must understand these and several other classes and their operation to get the most out of KryptOn.
An instance of MakoAgent handles everything you do with KryptOn. This agent facade simplifies usage and program development because all of the services are offerred in one place. Its easier to ensure your programs remain secure because all access to the sensitive keyring information is only only through the protocol of the agent, which includes loading and flushing sensitive information to and from image memory.
To do anything with KryptOn, you must create an agent:
myAgent := MakoAgent new
The Digital Keyring
There is nothing secret about the agent itself, only the keyring the agent is managing at the moment. An agent instance only handles requests for a single keyring at a time, not multiple.
The flash-drive key on your keychain can be thought of as a physical key, but where physical keys have cut angles and ridges that operate one and only one lock, the flash-drive key contains a directory of password-encrypted files that KryptOn constitutes into a first-class Smalltalk objects known as a digital "Keyring", specifically encoded to unlock your or others' digital information.
The first time using KryptOn, you will need to tell the agent to create you a digital keyring. As mentioned, this digital keyring is an object that spends most of its time in "stasis" as files on your portable flash drive.
To use KryptOn-secured systems you insert the portable flash-drive "key" so the keyring file can be loaded into memory. Like a car, you must leave the key in the slot while using the system because:
- You will not accidently leave your keys sitting there plugged in, not even to get up for a short break. Therefore when you leave with your keys the computer system will not be left unsecure.
- KryptOn automatically flushes the keyring (and all sensitive key information) from computer memory every few seconds. Upon the next need for key information, the key information will be reloaded from the keyring file. If the file is no longer available you will be prompted to reinsert the flash-drive.
To create your initial, digital keyring:
myAgent createKeyringFor: 'my primary keyring (or any descriptive name you wish)'
The agent now has a reference to this keyring in memory. Any new important key information that is added (imported) to the keyring will be immediately saved and then shortly purged from the computers memory, so the flash-drive must remain in the slot for secure operations.
Caring for the Keyring
The keyring object contains sensitive information, so you should never leave it exposed. The object must be loaded into memory for use by running programs. As a precaution, KryptOn will "timeout" each sensitive piece of information a few seconds after each use. If the physical key flash-drive was left in the slot, the password will not be required. This is because the computer can't know who is using, only whose key is inserted.
All agents also flush their keyrings just before the image is saved. All important information is wiped out (overwritten) before being dereferenced, so nothing important is left exposed in the image. Upon restarting the image, the first time your keyring is needed, the agent will once again look in the #keyringDirectory location remembered from the prior image save. If the directory or keyring file is not present (i.e., key not already inserted), a prompt for the location of your keyring file will appear (whereupon you must insert the microdrive into the USB slot to make it available before clicking OK). The sensitive information required for digital security operations will once again be loaded back into memory.
Saving the keyring file to your personal laptop hard disk or, worse, to a disk shared by others, is analagous to leaving your car keys unattended on your desk in an office; it is strongly discouraged unless you wish to run a reduced security. Even though the keyring file is encrypted and protected by password (just in case you ever lose your keychain), you won't know if anyone has made a copy of the keyring and trying to hack it. Passwords are much simpler to hack than the security key objects used by KryptOn, especially since the attacker will have unlimited tries.
So, a good rule of thumb is, use a good, long pass-phrase, and protect your keychain. Also, change the password occasionally, especially if you've ever typed your password in a public place.
If you do happen to accidently put your keyring file or other sensitive files in an unsafe place, do not simply delete them! First use a shredder program or the one that comes with KryptOn.
| privateFile |
privateFile := FileStream oldFileNamed: 'filename'.
[KryptOn shredFile: privateFile] ensure: [privateFile close].
This overwrites and flushes random streams of bytes to the file 20 times. After this it should be safe to delete.
Saving and Loading the Keyring
As previously mentioned, all access to your keyring must go through an agent. First you must instruct the agent where the keyring file should be kept:
myAgent keyringDirectory: 'x:\'
Notice that KryptOn wants a directory and not just a file. This simplifies the import process. Whenever someone gives you keys (capabilities) to some digital information to add to your keyring, the most natural thing to do is copy the files to your keyring directory. The flashdrive key is now "upgraded" to include whatever capabilities were just added (or communicate with whatever nodes were added).
Ok, lets get on with how to save the keyring:
?? It is up to you or your program to call saveKeyring ??
MakoNode - The object for Identification
KryptOn identifies people or a single digital-system by an instance of MakoNode. Anyone may have more than one MakoNode to represent themself so that security can be applied separately to different portions of their digital information. For example, you will want each database you own to have its own node so security can be separately applied. You might wish to have a separate node for specific systems you access. To communicate securely with other KryptOn users, you send secure MakoEnvelopes addressed to a Node they previously gave you (and, which you have copied into to your keyring directory). This process is explained in detail later. You give and receive nodes from others via the import/export functions provided by your MakoAgent.
Now that you have created a keyring, you can import nodes from another KryptOn user. Securely acquire the .node file from the other party. Place it into your agents #importDirectory and then tell your agent to import. (KryptOn will also check your import directory every time load your keyring is loaded).
After importing the MakoNodes representing other parties, you can now send them enciphered messages only they can decipher. KryptOn uses their node to encipher your message, and only they have the decoder "node kit" (see MakoNodeKit) for that node to decipher it.
If they also gave you ".cap" files to import, you will also have access to certain portions of the other party's digital information. Just plug your flash drive into the computer. These cap files are inside a digitally signed-and-sealed envelope addressed specifically to one of your nodes, therefore, capabilities can only be exchanged after .node files have first been exchanged. This "inconvenience" encourages diligence in acquiring an authentic Node.
MakoNodeKit - The Secret Portion of MakoNodes
Protection of your own digital information or use of capabilities requires creation of at least one MakoNode representing yourself. But MakoNodes are what you give others to identify you, so they can export capabilities specifically to that node that they know is cared for solely by you. More specifically, the MakoNode allows their computer system to know its you. Your computer system will have the same burden, to be sure the person sitting at the keyboard is you, therefore accessing your own digital information you wish to be secure requires generation of a MakoNode for yourself, regardless whether you intend to share that digital information with anyone else.
MakoNodes are always created automatically along with MakoNodeKit. Neither is useful without the other. To create the node-kit (and node), ask your agent:
This creates a NodeKit with the same name as your keyring. Like keyrings, MakoNodes can be independently named to help you (and others) keep track of who or what it represents. For example, one node might be named "accounts database", another "friends and family".
WARNING: This operation takes a very long time. Ferguson and Schneier specify 2048-bit ElGamal keys, and generation of these keys takes several hours, even for a fast 2006 computer. Therefore, your keyring also includes a 'keySupply', a collection where you may attach 2048-bit ElGamal keys that you've generated, but not necessarily ready to use.
myAgent generateElGamal: 2048; saveKeyring
The idea is, generate them while the opportunity is present (overnight, under your pillow), they will then be encrypted and stored on your keyring and available when you need them.
Naming is so important for identifying node-ownership, the name is actually called #id and should not be changed once assigned (if a different name is required then a new node should be created). Changing names allows confusion to creep in and could reduce security. It is ok to have more than one node with the same id, just look at their uuid's to determine which is the correct node.
Why shouldn't the #id be changed?
id's must remain constant or else "name confusion" could be used to attack. The #id must be part of the authentication for convenience because if only the nodes UUID + message were authenticated without the id, KryptOn users would be forced to visually match the UUID's, an unreasonable inconvenience, and people wouldn't do it anyway. Changing the name would requires a redistribution of the node to all parties, so you could as easily just distribute a new node.
MakoCapabilities - Authorizing access to digital information
In a KryptOn-aware program, you may write your program to guard certain data or behaviors. A user requests an operation and passes in a MakoCapability, which he has been previously given from the owner, with the request. The owner's (your) program must then explicitly ask an Agent to check the validity of capability presented. If a capability is not present or invalid, the program denies the request.
How to use Capabilities
Let's go through the process, with an example, step-by-step. Bob has a database server program using KryptOn. The database is a public-service database, anyone can read it, only a select group of administrators may update it. The database server program receives all requests into one method:
(self isGrantedToPublic: aDbRequest)
ifFalse: [ self authorizeCapability: aDbRequest capability ].
^ aDbRequest process
Some requests have to be public, the login request, for example. For the others Bob asks an Agent to authorize the capability accompanying the request:
"authorize aMakoCompactCapability as a valid capability."
by: self dbGrantorNode) ifFalse: [ self error: 'not authorized' ]
For the code above, #dbGrantorNode is the node representing this database. Bob has MakoNodeKits for several databases on his flash-drive key, each with its own set of authorizing capabilities. Therefore, the Agent requires the node we are making the request of to authorize its capability.
But where does aMakoCompactCapability come from and how does myAgent know what to do with it? First, determine what resources should be protected. In our example, we want the 'commit' command to only be allowed by the group who possess the commit capability. Therefore, in the initialization code of the database, he may specify to create an authorizer for this:
grantableFrom: self dbGrantorNode
This just defines this sort of access with meaningful names (#CommitRequest and #execute) that you may now tell KryptOn to create a MakoCapability object which may be given to your trustees:
from: self dbGrantorNode
to: 'John Doe'
Notice the last argument, the string 'John Doe' instead of a MakoNode of John's. Capabilities offer delegation of specific capabilities without compromising total system access (like what happens in password systems where John Doe shares his password just so his delegate can check one thing). But this string is meaningful in an access-log, and permits selective revocation, which will be discussed later.
Note that the flexibility of what to check is completely up to the KryptOn-aware program. Capabilities provide only #reference and #access to describe the resource being protected. In our example, the reference is the class-name of the request (CommitRequest), and #execute an arbitrary word chosen indicating 'execute access' to the commit command. Another capability may specify the reference as the id of a particular object and #access would be one of 'read' or 'update'.
Delivering the capability to the trustee
The #grante:accessOn:from:to: only creates and answers the MakoCapabilityObject in memory. For anyone to use it, including yourself, they need only put it into their Agent's #keyringDirectory.
To deliver the capability safely, you may:
exportFrom: self dbGrantorNode
We've already discussed dbGrantorNode, that's the node Bob uses to identify this database. "aliceNode" is the node for Alice, one of the administrators he wishes to grant commit access to. myAgent is just the same facade Agent which makes things easy.
A file is created in the agents #exportDirectory which is a serialized, signed-and-sealed envelope which can only be opened by the grantee, Alice.
If Alice's node has a #capabilitiesTargetUrl specified, a convenience method is available to automatically e-mail the envelope directly to Alice. In the future, other protocols besides e-mail may be supported.
Alice will then simply copy the .cap file to her keyring folder and commit-access is suddenly allowed.
Alice may further delegate her commit authority to her own trustee's by simply asking her Agent to export or email the node, just as it was to her, above.
This capabilities delegation is easy, security is not compromised because Alice can export just the capability she needs her delegate to have and nothing else. In a password system with centralized RBAC, one would hope that, for whatever Alice needed her delegate to perform, she would call the central security authority and request the proper access, instead of Alice sharing her password (which does happen).
MakoEnvelope - exchanging other objects securely
Once MakoNodes have been exchanged once in person, secure envelopes can be used to exchange more MakoNodes or MakoCapabilities. A MakoSealedEnvelope is a digitally secure object that ensures any message (or stream of bytes representing any kind of object) can be sent privately. The envelope is addressed to a particular MakoNode which you have received from someone. Only that person in who cares for the corresponding MakoNodeKit can open the envelope and see its contents.
To create an envelope, ask a MakoAgent:
This answers a MakoSealedEnvelope object which can be safely sent, over the Internet (for example e-mail) to the caretaker of the recipentNode. Inside this envelope are its enciphered 'bytes', which materialize into a MakoSignedEnvelope, whose own bytes are your message, alongside your digital signature, so the recipient can know it truly did come from the caretaker of the #signer.