Security



Security

The superior man, when resting in safety, does not forget that danger may come. When in a state of security he does not forget the possibility of ruin. When all is orderly, he does not forget that disorder may come. Thus his person is not endangered, and his States and all their clans are preserved.

—Confucius

It's the white elephant in the middle of the room that everybody can see, everybody recognizes, yet everybody tries desperately to ignore and goes to great lengths to work around. I speak of that most notorious of subjects in the programmer's lexicon, security.

The casual perception among most Java programmers is that security is deeply mystical, arcane, and incomprehensible. It's equal parts administration, cryptography, and FUD (fear, uncertainty, and doubt). Ask Java developers if their application is secure, and some will confidently and somewhat naïvely pronounce, "Absolutely!" while others will shrug their shoulders, look away uncomfortably, and try to steer the conversation back to safer, more comprehensible topics like brain surgery, object-relational mapping layers, and the joys of object pooling.

Unfortunately, such an attitude is roughly equivalent to that of a three-year-old playing hide-and-seek with his parents, putting his hands over his eyes, and pronouncing, "You can't see me!" Developers of enterprise applications, perhaps more so than in any other software development genre, need to be fully cognizant and aware of the security risks they face and how to mitigate them. Stories abound every day of corporations having credit card numbers stolen from their databases or losing millions to denial-of-service attacks and millions more to direct fraud and other illegal activities.

What makes this entire scenario worse is that most developers have only the most narrow-minded idea of what application security really is; within the Java community, mention of the word "security" evokes one of two responses: either "Java security—that's something to do with the applet sandbox, right?" or "Well, start with two very large prime numbers...."

Security is a large, rich, and exciting topic that stretches far beyond the Java applet sandbox and simple explanations of asymmetric key encryption. Whole books have spent hundreds of pages focusing on just one aspect of security and still not covered the topic completely, and thanks to the ever-escalating arms race between attackers and security experts, what was true today is legacy tomorrow. There is simply no way that one chapter in a book otherwise devoted to enterprise Java development can cover security in any depth. Instead, my goal is to provide you with a generalized primer on security topics and resources to consult if you wish to follow up with more detailed study. In addition, we'll take a quick look at leveraging the existing security mechanisms within the Java platform to make writing secure Java enterprise applications a little bit easier.

Before we get too deeply into the security discussions, however, in the interest of expediency let's establish up front some terminology unique to security discussions.

  • Authentication: This is the act of verifying that an entity within the system (a principal), whether an individual or some other, more nebulous entity (such as a corporation), is in fact who it claims to be. The act of authentication is simple: the security layer demands ("challenges") the entity to prove its identity, and the entity does so by presenting some form of credentials recognized by the security layer. If the credentials are genuine, the principal is successfully authenticated; if not, the security layer reacts accordingly, denying access or notifying another security system. Authentication comes in three basic forms: you can authenticate based on what you know, what you have, or what you are. Seen this way, it's obvious that authentication checks are a common fact of life and occur every day—I authenticate myself to my car every morning by presenting appropriate credentials (the car keys) to the security layer (the car door lock and ignition system). I authenticate myself to the guy taking my credit card to pay for lunch by presenting my credentials (my signature on the credit card slip and sometimes, my driver's license) to the security layer (the guy holding the card). We in American society have even begun to teach our kids the basics of authentication: many children are taught special "code words" that only someone legitimately sent by the children's parents to pick them up would know. A child forces an authentication check when he or she responds to "Your Mom told me to pick you up" by asking what the code word is. If the grownup doesn't know it, the child is told to find a recognizable icon of authority (e.g., a teacher, a policeman) and tell them. It's all the same basic principle.

  • Authorization: Authorization is the act of establishing what a principal within the system is allowed to do. In many cases, in real-life scenarios, successful authentication implies a certain authorization—for example, if I successfully authenticate myself to my car, I'm authorized to start the engine and drive it. My authorization stops, however, when I try to engage in activities that endanger other drivers on the road—speeding, swerving dangerously, and so on. Not that the car itself will stop me, but the police cruiser hiding behind the billboard will. The police, however, have full authorization to engage in whatever activity is necessary to enforce those same traffic laws, including the right to smash into my car to force it off the road. The authentication models are similar (do you have the keys?), but the authorization granted is very different. Within a software system, authorization determines the actions (permissions) granted to the various actors within the system—permission to add an item to the shopping cart, permission to cancel the shopping cart, permission to access the underlying table structure, and so on. Frequently, we'll group these permissions into sets, call them roles, and assign users to one or more roles as a means of simplifying administration of the system (see Item 63).

  • Cryptography: Cryptography is the science of taking a message (called plaintext) and producing a form of that message in a way that is unreadable to anyone except those who have the means by which to render the encrypted message (now called ciphertext) back into its plaintext form. Since the algorithms used to encrypt the message are often well-known (or easily reversible), most cryptographic algorithms rely on a key, a bit of data used as part of the algorithm to help make it more resistant to decryption by unwanted parties. If both sides of the message exchange need the same key to encrypt and decrypt the message, it is called symmetric key cryptography or, more colloquially, secret key cryptography. If each side can have one-half of a key pair, it is called asymmetric key cryptography or public-key/private-key cryptography.

  • Cryptanalysis: The "other half" of cryptography, cryptanalysis is the science of breaking an encrypted message back to its plaintext origins without having to know the key(s) with which the message was encrypted.

  • Steganography: This is the science of "hiding" a message within something else. For example, where a cryptographer seeks to encrypt the message and broadcast it in the clear, a steganographer instead chooses to broadcast an image file, with the message sprinkled within the image file in a way that leaves most of the image untouched, yet people who know about the image's role as a cover can retrieve the message. (Perhaps every 15th byte will in fact be a byte from the message rather than image data itself.) Steganography and cryptography are sometimes combined to make it that much more difficult to discover the plaintext message, on the theory that if you don't even know the message is there, you can't cryptanalyze it.

  • Alice, Bob, Mallory, Eve, and Trent: Believe it or not, these names aren't just chosen at random in cryptographic writings. In a security protocol discussion, Alice always initiates the conversation with Bob. Mallory is the malicious individual trying to disrupt, change, or redirect the conversation, while Eve is the passive eavesdropper who just wants to listen in on the conversation. Trent is the third party known and trusted by both Alice and Bob. These names help establish whom we're referring to during a security protocol discussion and are explained in more detail in Applied Cryptography [Schneier95].

  • Confidentiality: When I was in the sixth grade, I had a huge crush on my dream girl, Tracey Latipow. She sat two rows over, three seats up, and I thought she was just the most wonderful thing I had ever seen. Being a society-conscious sixth-grader, however, I couldn't just come out and admit that I liked her, particularly since my fragile ego would be absolutely crushed if she didn't like me in turn. But I had to know. So I devised a simple plan (one that has probably been used over and over again throughout history)—I would write a friend of hers a note asking the critical question. (Were I in sixth grade today, I would just text-message her on her cellphone, but such things didn't exist when I was 12.) Problem was, my sixth-grade teacher, Mr. Martin, frowned heavily on passing notes in class, and if he caught such activity, he would execute the ultimate punishment to a note-passing sixth grader: he would read the note out loud to the class. So I couldn't write the note in plain English—I needed some way to hide the message so that nobody but the intended recipient could read it. In formal cryptographic terms, this is called data confidentiality; because the note was being passed over an untrusted medium (the other kids in class), any one of whom could read the note as they handed it to the next person in the chain, the contents of the message must be made confidential. This is different from steganography, which is the act of hiding the message (which I did as well, by trying to keep the act of passing the note as subtle as possible, usually by doing it at recess or while Mr. Martin's back was turned).

  • Integrity: Going back to sixth grade for a moment, just making sure the data was hidden from incidental readers along the way wasn't enough. Suppose somebody figured out my most excellent code and decided to play a trick on me by pretending to be Tracey's friend and answering the question incorrectly. No end of embarrassment, particularly if the interceptor said "yes," and the real answer was "no"—I could very well end up making a fool of myself by admitting my crush to Tracey! In formal terms, what I was looking for here was data integrity, a reassurance that the message did, in fact, come from Tracey's friend and not some practical joker in the middle.

On these basic terms are enterprise security discussions founded.