UnitTest/ATestAgainstJava.java
/* |
Copyright (C) 2016 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
Shows how to generate results compatible with our code from Java. |
*/ |
// I ran this test with the following configuration: |
// |
// $ sw_vers |
// ProductName: Mac OS X |
// ProductVersion: 10.11.6 |
// BuildVersion: 15G31 |
// |
// $ java -version |
// java version "1.8.0_102" |
// Java(TM) SE Runtime Environment (build 1.8.0_102-b14) |
// Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode) |
// |
// I downloaded Java from the download site suggested when I ran `java` from |
// Terminal. |
// |
// To run the test: |
// |
// $ cd UnitTest |
// $ javac ATestAgainstJava.java && java -ea Main |
// |
// IMPORTANT: Many of the tests will fail unless you have the Java Cryptography Extension (JCE) |
// Unlimited Strength Jurisdiction Policy Files installed (*phew*). After downing that package |
// you'll find that the read me references a <java-home> path. With the configuration described |
// above, that path is `/Library/Java/JavaVirtualMachines/jdk1.8.0_102.jdk/Contents/Home/jre/`. |
// |
// Note that this code isn't intended to be a good example of Java programming; it's merely |
// sufficient to test the things I needed to test. |
import java.lang.*; |
import java.util.*; |
import java.io.*; |
import java.security.*; |
import java.security.cert.*; |
import java.security.spec.*; |
import javax.crypto.*; |
import javax.crypto.spec.*; |
import javax.xml.bind.DatatypeConverter; |
class QHex |
{ |
public static String hexStringFromBytes(byte[] bytes) |
{ |
return DatatypeConverter.printHexBinary(bytes).toLowerCase(); |
} |
public static byte[] bytesFromHexString(String string) |
{ |
return DatatypeConverter.parseHexBinary(string); |
} |
} |
class QIO |
{ |
public static byte[] bytesWithContentsOfFile(String fileName) throws IOException, NoSuchAlgorithmException |
{ |
RandomAccessFile f = new RandomAccessFile("../TestData/" + fileName, "r"); |
byte[] bytes = new byte[(int) f.length()]; |
f.readFully(bytes); |
f.close(); |
return bytes; |
} |
public static String stringWithContentsOfFile(String fileName) throws IOException, NoSuchAlgorithmException |
{ |
return new String(QIO.bytesWithContentsOfFile(fileName), "UTF-8"); |
} |
public static byte[] bytesWithDecodedContentsOfPEMFile(String fileName, String tag) throws IOException, NoSuchAlgorithmException |
{ |
String pemStr = QIO.stringWithContentsOfFile(fileName); |
String beginMarker = "-----BEGIN " + tag + "-----\n"; |
String endMarker = "-----END " + tag + "-----"; |
pemStr = pemStr.substring(pemStr.indexOf(beginMarker, 0)); |
// System.out.format("%s", pemStr); |
pemStr = pemStr.replace(beginMarker, ""); |
pemStr = pemStr.replace(endMarker, ""); |
return DatatypeConverter.parseBase64Binary(pemStr); |
} |
public static FileInputStream fileInputStreamForFile(String fileName) throws FileNotFoundException |
{ |
return new FileInputStream("../TestData/" + fileName); |
} |
} |
class Base64Tests |
{ |
public static void testBase64Encode() throws IOException, NoSuchAlgorithmException |
{ |
byte[] inputBytes = QIO.bytesWithContentsOfFile("test.cer"); |
String expectedOutputString = QIO.stringWithContentsOfFile("test.pem"); |
expectedOutputString = expectedOutputString.replace("\n", ""); // there's no way to tell printBase64Binary to add line breaks, so we strip them from the expected string |
String outputString = DatatypeConverter.printBase64Binary(inputBytes); |
assert outputString.equals(expectedOutputString); |
} |
public static void testBase64Decode() throws IOException, NoSuchAlgorithmException |
{ |
String inputString = QIO.stringWithContentsOfFile("test.pem"); |
byte[] expectedOutputBytes = QIO.bytesWithContentsOfFile("test.cer"); |
byte[] outputBytes = DatatypeConverter.parseBase64Binary(inputString); |
assert Arrays.equals(outputBytes, expectedOutputBytes); |
} |
} |
class DigestTests |
{ |
public static void testSHA() throws IOException, NoSuchAlgorithmException |
{ |
byte[] inputBytes = QIO.bytesWithContentsOfFile("test.cer"); |
String kDigestAlgorithms[] = { "SHA1", "SHA-224", "SHA-256", "SHA-384", "SHA-512" }; |
byte kDigestsOfTestDotCer[][] = { |
QHex.bytesFromHexString("c1ddfe7dd14c9b8dee83b46b87a408970fd2a83f"), |
QHex.bytesFromHexString("d71908c49c7c1563a829882f1ba6115e1616d1bdbb1d1f757265137b"), |
QHex.bytesFromHexString("d69cb53f849c80d7803294ee8fed312e917656986538d14224468185fac56289"), |
QHex.bytesFromHexString("b1cbdc8c517ad3b0b96436839bfc9cdaf75609c4d8f908444eb31675909912ae73252e0df8a6c8599e81f2a0a760f182"), |
QHex.bytesFromHexString("a1b17242359bb8dbb0cda8356991f65131ca1894ef9f797b296e68dacd300e0e179e28823cd69da1cccc8a3a8d7339bf2c1311b018c48a0e53d488e66df22250") |
}; |
assert kDigestAlgorithms.length == kDigestsOfTestDotCer.length; |
for (int i = 0; i < kDigestAlgorithms.length; i++) { |
String algorithm = kDigestAlgorithms[i]; |
byte[] expectedOutputBytes = kDigestsOfTestDotCer[i]; |
byte[] outputBytes = MessageDigest.getInstance(algorithm).digest(inputBytes); |
assert Arrays.equals(outputBytes, expectedOutputBytes); |
} |
} |
public static void testHMACSHA() throws IOException, NoSuchAlgorithmException, InvalidKeyException |
{ |
byte[] inputBytes = QIO.bytesWithContentsOfFile("test.cer"); |
String kDigestAlgorithms[] = { "HmacSHA1", "HmacSHA224", "HmacSHA256", "HmacSHA384", "HmacSHA512" }; |
byte kDigestsOfTestDotCer[][] = { |
QHex.bytesFromHexString("550a1da058c1b5df6ea167870ae6dbc92f0e0281"), |
QHex.bytesFromHexString("aea439459bf3b7732886d9345c7f2651de94c45ebfc320b1b49c3057"), |
QHex.bytesFromHexString("5ad394b17fb3f064079b0a21f25758550f7c8d9065803ae7271cb7bb86dac081"), |
QHex.bytesFromHexString("78b0fd6c8241261010ad92a9a91538aac46a90989eebdda0cb2564b2dea26061f341eb379d71af720d961c295fbbf5cc"), |
QHex.bytesFromHexString("7ab5c9a876bd52ca9a9cf643ba097e6847ac02797e69f5d39fbdb4ce70390098b978faa022889496c22f0c787e41b17fe9456bb648b2c66ceb53c2dc3cc2c16e") |
}; |
assert kDigestAlgorithms.length == kDigestsOfTestDotCer.length; |
byte[] keyBytes = QHex.bytesFromHexString("48656c6c6f20437275656c20576f726c6421"); |
for (int i = 0; i < kDigestAlgorithms.length; i++) { |
String algorithm = kDigestAlgorithms[i]; |
byte[] expectedOutputBytes = kDigestsOfTestDotCer[i]; |
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, algorithm); |
Mac mac = Mac.getInstance(algorithm); |
mac.init(keySpec); |
byte[] outputBytes = mac.doFinal(inputBytes); |
assert Arrays.equals(outputBytes, expectedOutputBytes); |
} |
} |
} |
class KeyDerivationTests |
{ |
public static void testPBKDF2() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException |
{ |
String passwordString = "Hello Cruel World!"; |
byte[] saltBytes = "Some salt sir?".getBytes("UTF-8"); |
String kAlgorithms[] = { "PBKDF2WithHmacSHA1", "PBKDF2WithHmacSHA224", "PBKDF2WithHmacSHA256", "PBKDF2WithHmacSHA384", "PBKDF2WithHmacSHA512" }; |
byte kExpected[][] = { |
QHex.bytesFromHexString("e56c27f5eed251db50a3"), |
QHex.bytesFromHexString("88597c3d039227ea2723"), |
QHex.bytesFromHexString("884185449fa0f5ea91bf"), |
QHex.bytesFromHexString("7c44bd93a3f5d732a667"), |
QHex.bytesFromHexString("d4537676e0af5274ca01") |
}; |
assert kAlgorithms.length == kExpected.length; |
for (int i = 0; i < kAlgorithms.length; i++) { |
String algorithm = kAlgorithms[i]; |
byte[] expectedKeyBytes = kExpected[i]; |
PBEKeySpec keySpec = new PBEKeySpec(passwordString.toCharArray(), saltBytes, 1000, 10 * 8); // keyLength is in bits! |
byte[] keyBytes = SecretKeyFactory.getInstance(algorithm).generateSecret(keySpec).getEncoded(); |
assert Arrays.equals(keyBytes, expectedKeyBytes); |
} |
} |
} |
class CryptorTests |
{ |
// AES-128 |
public static void testAES128ECBEncryption() throws IOException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchProviderException, BadPaddingException, NoSuchPaddingException |
{ |
byte[] inputBytes = QIO.bytesWithContentsOfFile("plaintext-336.dat"); |
byte[] expectedOutputBytes = QIO.bytesWithContentsOfFile("cyphertext-aes-128-ecb-336.dat"); |
byte[] keyBytes = QHex.bytesFromHexString("0C1032520302EC8537A4A82C4EF7579D"); |
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); |
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding"); |
cipher.init(Cipher.ENCRYPT_MODE, keySpec); |
byte[] outputBytes = cipher.doFinal(inputBytes); |
assert Arrays.equals(outputBytes, expectedOutputBytes); |
} |
public static void testAES128ECBDecryption() throws IOException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchProviderException, BadPaddingException, NoSuchPaddingException |
{ |
byte[] inputBytes = QIO.bytesWithContentsOfFile("cyphertext-aes-128-ecb-336.dat"); |
byte[] expectedOutputBytes = QIO.bytesWithContentsOfFile("plaintext-336.dat"); |
byte[] keyBytes = QHex.bytesFromHexString("0C1032520302EC8537A4A82C4EF7579D"); |
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); |
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding"); |
cipher.init(Cipher.DECRYPT_MODE, keySpec); |
byte[] outputBytes = cipher.doFinal(inputBytes); |
assert Arrays.equals(outputBytes, expectedOutputBytes); |
} |
public static void testAES128CBCEncryption() throws IOException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchProviderException, BadPaddingException, NoSuchPaddingException, InvalidAlgorithmParameterException |
{ |
byte[] inputBytes = QIO.bytesWithContentsOfFile("plaintext-336.dat"); |
byte[] expectedOutputBytes = QIO.bytesWithContentsOfFile("cyphertext-aes-128-cbc-336.dat"); |
byte[] keyBytes = QHex.bytesFromHexString("0C1032520302EC8537A4A82C4EF7579D"); |
byte[] ivBytes = QHex.bytesFromHexString("AB5BBEB426015DA7EEDCEE8BEE3DFFB7"); |
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); |
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); |
cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(ivBytes)); |
byte[] outputBytes = cipher.doFinal(inputBytes); |
assert Arrays.equals(outputBytes, expectedOutputBytes); |
} |
public static void testAES128CBCDecryption() throws IOException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchProviderException, BadPaddingException, NoSuchPaddingException, InvalidAlgorithmParameterException |
{ |
byte[] inputBytes = QIO.bytesWithContentsOfFile("cyphertext-aes-128-cbc-336.dat"); |
byte[] expectedOutputBytes = QIO.bytesWithContentsOfFile("plaintext-336.dat"); |
byte[] keyBytes = QHex.bytesFromHexString("0C1032520302EC8537A4A82C4EF7579D"); |
byte[] ivBytes = QHex.bytesFromHexString("AB5BBEB426015DA7EEDCEE8BEE3DFFB7"); |
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); |
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); |
cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(ivBytes)); |
byte[] outputBytes = cipher.doFinal(inputBytes); |
assert Arrays.equals(outputBytes, expectedOutputBytes); |
} |
// AES-256 |
public static void testAES256ECBEncryption() throws IOException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchProviderException, BadPaddingException, NoSuchPaddingException |
{ |
byte[] inputBytes = QIO.bytesWithContentsOfFile("plaintext-336.dat"); |
byte[] expectedOutputBytes = QIO.bytesWithContentsOfFile("cyphertext-aes-256-ecb-336.dat"); |
byte[] keyBytes = QHex.bytesFromHexString("0C1032520302EC8537A4A82C4EF7579D2b88e4309655eb40707decdb143e328a"); |
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); |
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding"); |
cipher.init(Cipher.ENCRYPT_MODE, keySpec); |
byte[] outputBytes = cipher.doFinal(inputBytes); |
assert Arrays.equals(outputBytes, expectedOutputBytes); |
} |
public static void testAES256ECBDecryption() throws IOException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchProviderException, BadPaddingException, NoSuchPaddingException |
{ |
byte[] inputBytes = QIO.bytesWithContentsOfFile("cyphertext-aes-256-ecb-336.dat"); |
byte[] expectedOutputBytes = QIO.bytesWithContentsOfFile("plaintext-336.dat"); |
byte[] keyBytes = QHex.bytesFromHexString("0C1032520302EC8537A4A82C4EF7579D2b88e4309655eb40707decdb143e328a"); |
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); |
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding"); |
cipher.init(Cipher.DECRYPT_MODE, keySpec); |
byte[] outputBytes = cipher.doFinal(inputBytes); |
assert Arrays.equals(outputBytes, expectedOutputBytes); |
} |
public static void testAES256CBCEncryption() throws IOException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchProviderException, BadPaddingException, NoSuchPaddingException, InvalidAlgorithmParameterException |
{ |
byte[] inputBytes = QIO.bytesWithContentsOfFile("plaintext-336.dat"); |
byte[] expectedOutputBytes = QIO.bytesWithContentsOfFile("cyphertext-aes-256-cbc-336.dat"); |
byte[] keyBytes = QHex.bytesFromHexString("0C1032520302EC8537A4A82C4EF7579D2b88e4309655eb40707decdb143e328a"); |
byte[] ivBytes = QHex.bytesFromHexString("AB5BBEB426015DA7EEDCEE8BEE3DFFB7"); |
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); |
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); |
cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(ivBytes)); |
byte[] outputBytes = cipher.doFinal(inputBytes); |
assert Arrays.equals(outputBytes, expectedOutputBytes); |
} |
public static void testAES256CBCDecryption() throws IOException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchProviderException, BadPaddingException, NoSuchPaddingException, InvalidAlgorithmParameterException |
{ |
byte[] inputBytes = QIO.bytesWithContentsOfFile("cyphertext-aes-256-cbc-336.dat"); |
byte[] expectedOutputBytes = QIO.bytesWithContentsOfFile("plaintext-336.dat"); |
byte[] keyBytes = QHex.bytesFromHexString("0C1032520302EC8537A4A82C4EF7579D2b88e4309655eb40707decdb143e328a"); |
byte[] ivBytes = QHex.bytesFromHexString("AB5BBEB426015DA7EEDCEE8BEE3DFFB7"); |
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); |
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); |
cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(ivBytes)); |
byte[] outputBytes = cipher.doFinal(inputBytes); |
assert Arrays.equals(outputBytes, expectedOutputBytes); |
} |
// AES-128 Pad CBC |
public static void testAES128PadCBCEncryption() throws IOException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchProviderException, BadPaddingException, NoSuchPaddingException, InvalidAlgorithmParameterException |
{ |
byte[] inputBytes = QIO.bytesWithContentsOfFile("plaintext-332.dat"); |
byte[] expectedOutputBytes = QIO.bytesWithContentsOfFile("cyphertext-aes-128-cbc-332.dat"); |
byte[] keyBytes = QHex.bytesFromHexString("0C1032520302EC8537A4A82C4EF7579D"); |
byte[] ivBytes = QHex.bytesFromHexString("AB5BBEB426015DA7EEDCEE8BEE3DFFB7"); |
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); |
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); |
cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(ivBytes)); |
byte[] outputBytes = cipher.doFinal(inputBytes); |
assert Arrays.equals(outputBytes, expectedOutputBytes); |
} |
public static void testAES128PadCBCDecryption() throws IOException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchProviderException, BadPaddingException, NoSuchPaddingException, InvalidAlgorithmParameterException |
{ |
byte[] inputBytes = QIO.bytesWithContentsOfFile("cyphertext-aes-128-cbc-332.dat"); |
byte[] expectedOutputBytes = QIO.bytesWithContentsOfFile("plaintext-332.dat"); |
byte[] keyBytes = QHex.bytesFromHexString("0C1032520302EC8537A4A82C4EF7579D"); |
byte[] ivBytes = QHex.bytesFromHexString("AB5BBEB426015DA7EEDCEE8BEE3DFFB7"); |
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); |
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); |
cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(ivBytes)); |
byte[] outputBytes = cipher.doFinal(inputBytes); |
assert Arrays.equals(outputBytes, expectedOutputBytes); |
} |
// AES-256 Pad CBC |
public static void testAES256PadCBCEncryption() throws IOException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchProviderException, BadPaddingException, NoSuchPaddingException, InvalidAlgorithmParameterException |
{ |
byte[] inputBytes = QIO.bytesWithContentsOfFile("plaintext-332.dat"); |
byte[] expectedOutputBytes = QIO.bytesWithContentsOfFile("cyphertext-aes-256-cbc-332.dat"); |
byte[] keyBytes = QHex.bytesFromHexString("0C1032520302EC8537A4A82C4EF7579D2b88e4309655eb40707decdb143e328a"); |
byte[] ivBytes = QHex.bytesFromHexString("AB5BBEB426015DA7EEDCEE8BEE3DFFB7"); |
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); |
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); |
cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(ivBytes)); |
byte[] outputBytes = cipher.doFinal(inputBytes); |
assert Arrays.equals(outputBytes, expectedOutputBytes); |
} |
public static void testAES256PadCBCDecryption() throws IOException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchProviderException, BadPaddingException, NoSuchPaddingException, InvalidAlgorithmParameterException |
{ |
byte[] inputBytes = QIO.bytesWithContentsOfFile("cyphertext-aes-256-cbc-332.dat"); |
byte[] expectedOutputBytes = QIO.bytesWithContentsOfFile("plaintext-332.dat"); |
byte[] keyBytes = QHex.bytesFromHexString("0C1032520302EC8537A4A82C4EF7579D2b88e4309655eb40707decdb143e328a"); |
byte[] ivBytes = QHex.bytesFromHexString("AB5BBEB426015DA7EEDCEE8BEE3DFFB7"); |
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); |
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); |
cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(ivBytes)); |
byte[] outputBytes = cipher.doFinal(inputBytes); |
assert Arrays.equals(outputBytes, expectedOutputBytes); |
} |
} |
class RSATests |
{ |
static PrivateKey sPrivateKey; |
static PublicKey sPublicKey; |
public static void setup() throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, InvalidKeySpecException |
{ |
// private key |
KeyStore keyStore = KeyStore.getInstance("PKCS12"); |
keyStore.load(QIO.fileInputStreamForFile("private.p12"), null); |
if (false) { |
for (Enumeration<String> e = keyStore.aliases(); e.hasMoreElements(); ) { |
System.out.format("%s\n", e.nextElement()); |
} |
} |
sPrivateKey = (PrivateKey) keyStore.getKey("testprivatekey", "test".toCharArray()); |
// public key |
byte[] publicKeyBytes = QIO.bytesWithDecodedContentsOfPEMFile("public.pem", "PUBLIC KEY"); |
X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKeyBytes); |
sPublicKey = KeyFactory.getInstance("RSA").generatePublic(spec); |
} |
static int verifyCountForFile(String fileName) throws IOException, FileNotFoundException, CertificateException, NoSuchAlgorithmException, InvalidKeyException, SignatureException, InvalidKeySpecException |
{ |
int result = 0; |
byte[] fileBytes = QIO.bytesWithContentsOfFile(fileName + ".cer"); |
assert sPublicKey != null; // set up by setup() method |
String kAlgorithms[] = { "SHA1withRSA", "SHA224withRSA", "SHA256withRSA", "SHA384withRSA", "SHA512withRSA" }; |
String kSignatures[] = { |
"test.cer-sha1.sig", |
"test.cer-sha2-224.sig", |
"test.cer-sha2-256.sig", |
"test.cer-sha2-384.sig", |
"test.cer-sha2-512.sig" |
}; |
assert kAlgorithms.length == kSignatures.length; |
for (int i = 0; i < kAlgorithms.length; i++) { |
String algorithm = kAlgorithms[i]; |
byte[] signatureBytes = QIO.bytesWithContentsOfFile(kSignatures[i]); |
Signature sig = Signature.getInstance(algorithm); |
sig.initVerify(sPublicKey); |
sig.update(fileBytes); |
if (sig.verify(signatureBytes)) { |
result += 1; |
} |
} |
return result; |
} |
public static void testRSASHAVerify() throws IOException, FileNotFoundException, CertificateException, NoSuchAlgorithmException, InvalidKeyException, SignatureException, InvalidKeySpecException |
{ |
assert RSATests.verifyCountForFile("test") == 5; |
assert RSATests.verifyCountForFile("test-corrupted") == 0; |
} |
public static void testRSASHASign() throws IOException, NoSuchAlgorithmException, InvalidKeyException, SignatureException, InvalidKeySpecException |
{ |
byte[] fileBytes = QIO.bytesWithContentsOfFile("test.cer"); |
assert sPrivateKey != null; // set up by setup() method |
String kAlgorithms[] = { "SHA1withRSA", "SHA224withRSA", "SHA256withRSA", "SHA384withRSA", "SHA512withRSA" }; |
String kSignatures[] = { |
"test.cer-sha1.sig", |
"test.cer-sha2-224.sig", |
"test.cer-sha2-256.sig", |
"test.cer-sha2-384.sig", |
"test.cer-sha2-512.sig" |
}; |
assert kAlgorithms.length == kSignatures.length; |
for (int i = 0; i < kAlgorithms.length; i++) { |
String algorithm = kAlgorithms[i]; |
byte[] expectedSignatureBytes = QIO.bytesWithContentsOfFile(kSignatures[i]); |
Signature sig = Signature.getInstance(algorithm); |
sig.initSign(sPrivateKey); |
sig.update(fileBytes); |
byte[] signatureBytes = sig.sign(); |
assert Arrays.equals(signatureBytes, expectedSignatureBytes); |
} |
} |
// When you encrypt with padding you can't test a fixed encryption because the padding |
// adds some randomness so that no two encryptions are the same. Thus, we can only test |
// the round trip case (`testRSASmallCryptor`) and the decrypt case (`testRSADecryptPKCS1` |
// and `testRSADecryptOAEP`). |
public static void testRSASmallCryptor() throws InvalidKeySpecException, IOException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException |
{ |
byte[] fileBytes = QIO.bytesWithContentsOfFile("plaintext-32.dat"); |
assert sPublicKey != null; // set up by setup() method |
assert sPrivateKey != null; // set up by setup() method |
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); |
cipher.init(Cipher.ENCRYPT_MODE, sPublicKey); |
byte[] encryptedBytes = cipher.doFinal(fileBytes); |
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); |
cipher.init(Cipher.DECRYPT_MODE, sPrivateKey); |
byte[] decryptedBytes = cipher.doFinal(encryptedBytes); |
assert Arrays.equals(decryptedBytes, fileBytes); |
} |
public static void testRSADecryptPKCS1() throws InvalidKeySpecException, IOException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException |
{ |
byte[] cyphertext32Bytes = QIO.bytesWithContentsOfFile("cyphertext-rsa-pkcs1-32.dat"); |
byte[] fileBytes = QIO.bytesWithContentsOfFile("plaintext-32.dat"); |
assert sPublicKey != null; // set up by setup() method |
assert sPrivateKey != null; // set up by setup() method |
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); |
cipher.init(Cipher.DECRYPT_MODE, sPrivateKey); |
byte[] decryptedBytes = cipher.doFinal(cyphertext32Bytes); |
assert Arrays.equals(decryptedBytes, fileBytes); |
} |
public static void testRSADecryptOAEP() throws InvalidKeySpecException, IOException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException |
{ |
byte[] cyphertext32Bytes = QIO.bytesWithContentsOfFile("cyphertext-rsa-oaep-32.dat"); |
byte[] fileBytes = QIO.bytesWithContentsOfFile("plaintext-32.dat"); |
assert sPublicKey != null; // set up by setup() method |
assert sPrivateKey != null; // set up by setup() method |
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPadding"); |
cipher.init(Cipher.DECRYPT_MODE, sPrivateKey); |
byte[] decryptedBytes = cipher.doFinal(cyphertext32Bytes); |
assert Arrays.equals(decryptedBytes, fileBytes); |
} |
} |
class Main |
{ |
public static void main (String[] args) throws Exception |
{ |
Base64Tests.testBase64Encode(); |
Base64Tests.testBase64Decode(); |
DigestTests.testSHA(); |
DigestTests.testHMACSHA(); |
KeyDerivationTests.testPBKDF2(); |
CryptorTests.testAES128ECBEncryption(); |
CryptorTests.testAES128ECBDecryption(); |
CryptorTests.testAES128CBCEncryption(); |
CryptorTests.testAES128CBCDecryption(); |
CryptorTests.testAES256ECBEncryption(); |
CryptorTests.testAES256ECBDecryption(); |
CryptorTests.testAES256CBCEncryption(); |
CryptorTests.testAES256CBCDecryption(); |
CryptorTests.testAES128PadCBCEncryption(); |
CryptorTests.testAES128PadCBCDecryption(); |
CryptorTests.testAES256PadCBCEncryption(); |
CryptorTests.testAES256PadCBCDecryption(); |
RSATests.setup(); |
RSATests.testRSASHAVerify(); |
RSATests.testRSASHASign(); |
RSATests.testRSASmallCryptor(); |
RSATests.testRSADecryptPKCS1(); |
RSATests.testRSADecryptOAEP(); |
System.out.format("Success.\n"); |
} |
} |
Copyright © 2016 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2016-11-17