Computer Security
CS 240: Advanced Software Construction
Overview
Computer Security
Computer Security
Some Important Security Goals
Foundational Concepts
Cryptographic Hash Functions
Cryptographic (One-Way) Hash Functions
One-Way: Given the Digest (or output),
you cannot recover the Input
Deterministic: Given the same Input, it
Produces the same Digest (or output)
Fixed-Size: The Digest is always the same size (e.g., 160 bits), regardless of the Input size
Pseudo-Random: The output seems statistically random, even though it is not (small change to Input makes the Digest totally different)
Cryptographic Hash Algorithms
Hashing data in Java
package demo;��import java.security.MessageDigest;�import java.security.NoSuchAlgorithmException;�import java.nio.charset.StandardCharsets;���public class CryptoHashFunctionDemo {�� public static void main(String[] args) throws NoSuchAlgorithmException {�� String[] allInputs = new String[]{� "Fox",� "Fox",� "The red fox jumps over the blue dog",� "The red fox jumps ouer the blue dog",� };�� for (String input : allInputs) {� // Convert character string to array of bytes� byte[] inputBytes = input.getBytes(StandardCharsets.UTF_8);�� // Calculate message digest� byte[] digestBytes = hashData(inputBytes);�� System.out.println(input);� System.out.println(Utils.bytesToHex(digestBytes));� System.out.println();� }� }�� public static byte[] hashData(byte[] data) throws NoSuchAlgorithmException {� � MessageDigest md = MessageDigest.getInstance("SHA-256");� � byte[] digest = md.digest(data);� � return digest;� }�}��
Cryptographic Hashing Applications
Cryptographic Hashing Applications
Secure user password storage and verification
Password hashing
Password | Password Hash |
auhsoJ | 39e717cd3f5c4be78d97090c69f4e655 |
hsifdrowS | f567c40623df407ba980bfad6dff5982 |
1010NO1Z | 711f1f88006a48859616c3a5cbcc0377 |
sinocarD tupaC | fb74376102a049b9a7c5529784763c53 |
……….. | ……….. |
Database
Dictionary
Password hashing
Salted password hashing
Password hash functions
Password hash example - Bcrypt
import org.mindrot.jbcrypt.BCrypt;
public class PasswordExample {
public static void main(String[] args) {
String secret = "toomanysecrets";
String hash = BCrypt.hashpw(secret, BCrypt.gensalt());
// Salt is the first 22 characters after the third $
System.out.println(hash);
String[] passwords = {"cow", "toomanysecrets", "password"};
for (var pw : passwords) {
var match = BCrypt.checkpw(pw, hash) ? "==" : "!=";
System.out.printf("%s %s %s%n", pw, match, secret);
}
}
}
Data Encryption
Encryption / Decryption
Encryption Algorithms
Symmetric (or Secret) Key Encryption
Symmetric Key �Encryption in Java
package demo;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.security.SecureRandom;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
public class SymmetricKeyEncryptionDemo {
public static void main(String[] args) throws Exception {
// Create AES key and initialization vector
SecretKey aesKey = createAesKey();
IvParameterSpec aesInitVector = createAesInitVector();
// Encrypt file
try (FileInputStream inputStream = new FileInputStream(args[0]);
FileOutputStream outputStream = new FileOutputStream("encrypted-file")) {
aesEncrypt(inputStream, outputStream, aesKey, aesInitVector);
}
// Decrypt file
try (FileInputStream inputStream = new FileInputStream("encrypted-file");
FileOutputStream outputStream = new FileOutputStream("decrypted-file")) {
aesDecrypt(inputStream, outputStream, aesKey, aesInitVector);
}
}
private static SecretKey createAesKey() throws Exception
{
// Generate a pseudo-random AES encryption key (here we use a 256-bit key)
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256);
SecretKey key = keyGen.generateKey();
return key;
}
private static IvParameterSpec createAesInitVector() throws Exception
{
// Generate a pseudo-random AES "initialization vector" (128 bits)
var ivBytes = new byte[16];
new SecureRandom().nextBytes(ivBytes);
return new IvParameterSpec(ivBytes);
}
private static void aesEncrypt(InputStream inputStream, OutputStream outputStream,
SecretKey key, IvParameterSpec initVector) throws Exception {
runAes(Cipher.ENCRYPT_MODE, inputStream, outputStream, key, initVector);
}
private static void aesDecrypt(InputStream inputStream, OutputStream outputStream,
SecretKey key, IvParameterSpec initVector) throws Exception {
runAes(Cipher.DECRYPT_MODE, inputStream, outputStream, key, initVector);
}
private static void runAes(int cipherMode, InputStream inputStream, OutputStream outputStream,
SecretKey key, IvParameterSpec initVector) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(cipherMode, key, initVector);
byte[] inputBytes = new byte[64];
byte[] outputBytes = null;
int bytesRead;
while ((bytesRead = inputStream.read(inputBytes)) != -1) {
outputBytes = cipher.update(inputBytes, 0, bytesRead);
if (outputBytes != null) {
outputStream.write(outputBytes);
}
}
outputBytes = cipher.doFinal();
if (outputBytes != null) {
outputStream.write(outputBytes);
}
outputStream.flush();
}
}
Asymmetric (or Public ) Key Encryption
Public Key Encryption
Public Key Encryption
Public Key Encryption� in Java
package demo;
import javax.crypto.Cipher;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;
public class PublicKeyEncryptionDemo {
public static void main(String[] args) throws Exception {
// Create and save RSA key pair
KeyPair keyPair = createRsaKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
Files.write(Paths.get("public-key"), publicKey.getEncoded());
Files.write(Paths.get("private-key"), privateKey.getEncoded());
Key encryptionKey = publicKey;
Key decryptionKey = privateKey;
//Key encryptionKey = privateKey;
//Key decryptionKey = publicKey;
final String PLAIN_TEXT = "Four score and seven years ago our fathers brought forth, upon this continent," +
" a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal.";
byte[] plainTextBytes = PLAIN_TEXT.getBytes(StandardCharsets.UTF_8);
ByteArrayInputStream inputStream = null;
ByteArrayOutputStream outputStream = null;
// Encrypt data
inputStream = new ByteArrayInputStream(plainTextBytes);
outputStream = new ByteArrayOutputStream();
rsaEncrypt(inputStream, outputStream, encryptionKey);
byte[] cipherTextBytes = outputStream.toByteArray();
System.out.println(Utils.bytesToHex(cipherTextBytes));
System.out.println();
// Decrypt data
inputStream = new ByteArrayInputStream(cipherTextBytes);
outputStream = new ByteArrayOutputStream();
rsaDecrypt(inputStream, outputStream, decryptionKey);
byte[] decryptedPlainTextBytes = outputStream.toByteArray();
String decryptedPlainText = new String(decryptedPlainTextBytes, StandardCharsets.UTF_8);
System.out.println(decryptedPlainText);
System.out.println();
}
private static KeyPair createRsaKeyPair() throws Exception
{
var keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(2048);
KeyPair keyPair = keyPairGen.generateKeyPair();
return keyPair;
}
private static void rsaEncrypt(InputStream inputStream, OutputStream outputStream, Key key) throws Exception {
runRsa(Cipher.ENCRYPT_MODE, inputStream, outputStream, key);
}
private static void rsaDecrypt(InputStream inputStream, OutputStream outputStream, Key key) throws Exception {
runRsa(Cipher.DECRYPT_MODE, inputStream, outputStream, key);
}
private static void runRsa(int cipherMode, InputStream inputStream, OutputStream outputStream,
Key key) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(cipherMode, key);
byte[] inputBytes = new byte[64];
byte[] outputBytes = null;
int bytesRead;
while ((bytesRead = inputStream.read(inputBytes)) != -1) {
outputBytes = cipher.update(inputBytes, 0, bytesRead);
if (outputBytes != null) {
outputStream.write(outputBytes);
}
}
outputBytes = cipher.doFinal();
if (outputBytes != null) {
outputStream.write(outputBytes);
}
outputStream.flush();
}
}
Public Key Encryption
Encryption Applications
Password Managers
Secure Key Exchange
Secure Key Exchange
Secure Key Exchange
1
Data Receiver (Alice)
Data Sender (Bob)
Alice sends Bob her public key (eg,RSA)
Bob generates a random
symmetric key (eg,AES)
Bob encrypts symmetric
key using Alice’s public key
Bob sends Alice encrypted symmetric key
Alice decrypts encrypted symmetric key using her private key
2
3
4
5
Bob encrypts data using symmetric key
6
Bob sends encrypted data to Alice
7
Alice decrypts encrypted data using symmetric key
8
Secure Key Exchange
Secure Communication using HTTPS
Key Exchange in HTTPS/TLS Handshake
1
Server
Client
Client sends Server a random number (Client Random)
Client sends Server another random number (Pre Master Secret) that is encrypted with Server’s public key
Server decrypts Pre Master Secret using its private key
2
4
5
Both Client and Server use Client Random, Server Random, Pre-Master Secret to generate the same symmetric key (eg, AES)
6
Server sends Client a random number (Server Random)
3
Server sends Client its public key cert (eg,RSA)
Client and Server exchange data encrypted with generated symmetric key
7
HTTPS/TLS Server Authentication
HTTPS/TLS Server Authentication
HTTPS/TLS Server Authentication
Self-Signed Certificates for Development/Testing
# Create a 10-year self-signed certificate
�openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 3650 -nodes \
-subj "/C=US/ST=Oregon/L=Portland/O=Company Name/OU=Org/CN=www.example.com"
Digital Signatures
Digital Signatures
Creating a Digital Signature
Verifying a Digital Signature
Digital Signature Applications