diff --git a/.travis.yml b/.travis.yml
index bab5140..5c77f1d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,8 +1,18 @@
language: java
jdk:
- - oraclejdk8
+ - openjdk8
+ - oraclejdk9
+ - openjdk9
+ - oraclejdk11
+ - openjdk11
+ - oraclejdk13
+ - openjdk13
+ #- oraclejdk14
+ #- openjdk14
+ #- oraclejdk15
+ #- openjdk15
addons:
- sonarqube:
+ sonarcloud:
organization: "kmindi-github" # the key of the org you chose at step #3
cache:
directories:
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..1e64ef8
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,118 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
+and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+
+## [Unreleased]
+
+## [0.4.2] - 2020-02-16
+
+### Changed
+
+- Changed gradle version to 6.1.1
+- Changed used jdks in travis
+
+## [0.4.1] - 2018-08-02
+
+### Fixed
+
+- Fixed inclusion of source code links to old files
+
+## [0.4.0] - 2018-08-02
+
+### Changed
+
+- Changed class names to conform with guidelines
+- Added demonstrate-methods for all examples
+- Corrected meta format for file encryption example
+
+### Fixed
+
+- Added missing UTF-8 encoding in assymetric encryption example
+- Fixed file encryption not needing trim anymore
+- Fixed Headings according to guidlines
+- Fixed import statements not expclicit in file encryption example
+
+## [0.3.0] - 2018-07-18
+
+### Changed
+
+- Changed PBKDF2 hash function to SHA-512
+- Increased PBKDF2 salt size to 64 bytes (equal to SHA-512 size)
+- Increased PBKDF2 iterations to 10000
+- Refactored variable names
+- Refactored main methods to call a demonstrate...-method
+
+### Fixed
+
+- Exceptions were logged including the stack trace, now only the localized message is logged
+
+## [0.2.0] - 2018-05-13
+
+### Changed
+
+- Fixed version link in Changelog
+- Refactored examples
+- Updated class comments
+
+### Removed
+
+- Removed easy object oriented examples that used a separate class
+- Removed mentions of the need for unlimited policy files (unlimited is default since JDK / Java SE 9)
+- Removed commented out code
+
+## [0.1.1] - 2018-04-28
+
+### Changed
+
+- fixed Changelog
+
+## [0.1.0] - 2018-04-28
+
+### Added
+
+- added Changelog
+- added Asymmetric RSA String Encryption
+
+## [X.Y.Z] - XXXX-XX-XX (TEMPLATE for new versions)
+
+### Added
+
+- added something
+- added something else
+
+### Changed
+
+- changed something
+- changed something else
+
+### Deprecated
+
+- deprecated something
+- deprecated something else
+
+### Removed
+
+- removed something
+- removed something else
+
+### Fixed
+
+- fixed something
+- fixed something else
+
+### Security
+
+- made some security relevant changes
+- made other security relevant changes
+
+[Unreleased]: https://github.com/cryptoexamples/java-crypto-examples/compare/v0.4.2...HEAD
+[0.4.2]: https://github.com/cryptoexamples/java-crypto-examples/compare/v0.4.1...v0.4.2
+[0.4.1]: https://github.com/cryptoexamples/java-crypto-examples/compare/v0.4.0...v0.4.1
+[0.4.0]: https://github.com/cryptoexamples/java-crypto-examples/compare/v0.3.0...v0.4.0
+[0.3.0]: https://github.com/cryptoexamples/java-crypto-examples/compare/v0.2.0...v0.3.0
+[0.2.0]: https://github.com/cryptoexamples/java-crypto-examples/compare/v0.1.1...v0.2.0
+[0.1.1]: https://github.com/cryptoexamples/java-crypto-examples/compare/v0.1.0...v0.1.1
+[0.1.0]: https://github.com/cryptoexamples/java-crypto-examples/releases/tag/v0.1.0
\ No newline at end of file
diff --git a/README.md b/README.md
index d2b213f..2414c89 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,21 @@
-# java-crypto-examples for [cryptoexamples.com](http://cryptoexamples.com)
+# java-crypto-examples for [CryptoExamples](https://www.cryptoexamples.com)
-Example code for cryptographic use cases. Used in [crypto-examples](https://github.com/kmindi/crypto-examples)
+Example code for cryptographic use cases. Used in [CryptoExamples](https://github.com/cryptoexamples/CryptoExamples)
-
-
-
-
+[](https://travis-ci.org/SonarSource/cryptoexamples/java-crypto-examples)
+[](https://sonarcloud.io/dashboard?id=java-crypto-examples)
+[](https://sonarcloud.io/component_measures?id=java-crypto-examples&metric=sqale_rating)
+[](https://sonarcloud.io/component_measures?id=java-crypto-examples&metric=security_rating)
+[](https://sonarcloud.io/component_measures?id=java-crypto-examples&metric=reliability_rating)
+
+[](https://sonarcloud.io/component_measures?id=java-crypto-examples&metric=code_smells)
+[](https://sonarcloud.io/component_measures?id=java-crypto-examples&metric=bugs)
+[](https://sonarcloud.io/component_measures?id=java-crypto-examples&metric=sqale_index)
+[](https://sonarcloud.io/component_measures?id=java-crypto-examples&metric=coverage)
+[](https://sonarcloud.io/component_measures?id=java-crypto-examples&metric=vulnerabilities)
+[](https://sonarcloud.io/component_measures?id=java-crypto-examples&metric=duplicated_lines_density)
+
+
## License
diff --git a/build.gradle b/build.gradle
index 8046bbc..83f2747 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,5 +1,5 @@
plugins {
- id "org.sonarqube" version "2.3"
+ id "org.sonarqube" version "2.6.2"
}
group 'com.cryptoexamples.java'
@@ -18,16 +18,5 @@ dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
}
-tasks.withType(Test) { task ->
- jacoco {
- append = false
- }
-}
-jacocoTestReport {
- reports {
- xml.enabled true
- csv.enabled false
- html.destination "${buildDir}/jacocoHtml"
- }
-}
\ No newline at end of file
+
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index aa674ec..a362cda 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
diff --git a/java_easy_AES_file_encryption.md b/java_easy_AES_file_encryption.md
deleted file mode 100644
index 54bdc4b..0000000
--- a/java_easy_AES_file_encryption.md
+++ /dev/null
@@ -1,22 +0,0 @@
----
-title: Java File Encryption using JDK
-keywords: sample
-summary: "Java based string encryption"
-permalink: java_easy_AES_file_encryption.html
-folder: Java JDK
-tags: [Java, AES, GCM, PBKDF2, Salt, AEAD]
----
-
-## Sample Code for Java based symmetric file encryption
-
-```java
-{% include_relative src/main/java/com/cryptoexamples/java/ExampleEncryptedFile.java %}
-```
-
-### EncryptedFile encapsulating class using AES-GCM and PBKDF2
-```java
-{% include_relative src/main/java/com/cryptoexamples/java/EncryptedFile.java %}
-```
-
-
-{% include links.html %}
diff --git a/java_easy_AES_string_encryption.md b/java_easy_AES_string_encryption.md
deleted file mode 100644
index a5e8262..0000000
--- a/java_easy_AES_string_encryption.md
+++ /dev/null
@@ -1,22 +0,0 @@
----
-title: Java String Encryption using JDK
-keywords: sample
-summary: "Java based string encryption"
-permalink: java_easy_AES_string_encryption.html
-folder: Java JDK
-tags: [Java, AES, GCM, PBKDF2, Salt, AEAD]
----
-
-## Sample Code for Java based symmetric encryption
-
-```java
-{% include_relative src/main/java/com/cryptoexamples/java/ExampleEncryptedString.java %}
-```
-
-### EncryptedString Encapsulating class using AES-GCM and PBKDF2
-```java
-{% include_relative src/main/java/com/cryptoexamples/java/EncryptedString.java %}
-```
-
-
-{% include links.html %}
diff --git a/java_file_encryption_symmetric_password_based.md b/java_file_encryption_symmetric_password_based.md
index 583d949..5c7a3a5 100644
--- a/java_file_encryption_symmetric_password_based.md
+++ b/java_file_encryption_symmetric_password_based.md
@@ -1,21 +1,51 @@
---
-title: Password based symmetric file encryption in Java using JDK
+title: Java Password based symmetric file encryption using JDK
keywords: sample
summary: "Password based symmetric file encryption in Java"
permalink: java_file_encryption_symmetric_password_based.html
folder: Java JDK
+references: [
+ # Place a list of references used to create and/or understand this example.
+ {
+ url: "https://docs.oracle.com/javase/10/docs/api/javax/crypto/Cipher.html",
+ description: "Java JDK Ciper"
+ }
+]
+authors: [
+ {
+ name: "Kai Mindermann",
+ url: "https://github.com/kmindi"
+ }
+]
+# List all reviewers that reviewed this version of the example. When the example is updated all old reviews
+# must be removed from the list below and the code has to be reviewed again. The complete review process
+# is documented in the main repository of CryptoExamples
+current_reviews: [
+
+]
+# Indicates when this example was last updated/created. Reviews don't change this.
+last_updated: "2020-02-16"
tags: [Java, AES, GCM, PBKDF2, Salt, AEAD]
---
## Use cases
-- password based encryption of a file
-- previously shared common secret (password)
+- Password based symmetric encryption of a file
+
+## Java version
+
+- openjdk8
+- oraclejdk9
+- openjdk9
+- oraclejdk11
+- openjdk11
+- oraclejdk13
+- openjdk13
-## Sample Code for Java based symmetric file encryption using AES-GCM and PBKDF2
+## Example Code for Java Password based symmetric file encryption using AES-GCM and PBKDF2
```java
-{% include_relative src/main/java/com/cryptoexamples/java/ExampleFileEncryptionInOneMethod.java %}
+{% include_relative src/main/java/com/cryptoexamples/java/ExampleFileEncryption.java %}
```
diff --git a/java_landing_page.md b/java_landing_page.md
index df75b30..ccdbb84 100644
--- a/java_landing_page.md
+++ b/java_landing_page.md
@@ -9,11 +9,11 @@ is_landingpage: 1
# Available Crypto Scenarios and Use Cases
-| | All in One | Easy Object oriented |
-|-------------------------------------------------|----------------------------------------|--------------------------------------|
-| Symmetric Encryption | [String Encryption (password based) ✔](java_string_encryption_password_based_symmetric.html)
[String Encryption (key based) ✔](java_string_encryption_key_based_symmetric.html)
[File Encryption ✔](java_file_encryption_symmetric_password_based.html) | [String Encryption with separate class ✔](java_easy_AES_string_encryption.html)
[File Encryption with separate class ✔](java_easy_AES_file_encryption.html) |
-| Asymmetric Encryption / Public Key Cryptography | | |
-| Key Storage | | |
-| Hashing | [String Hash ✔](java_string_hash.html) | N/A |
-| Crypto Provider Setup | | |
-| Digital Signatures | [String Signing ✔](java_string_sign.html) | |
+| | All in One |
+|-------------------------------------------------|----------------------------------------|
+| Symmetric Encryption | [Symmetric String Encryption (password based) ✔](java_string_encryption_password_based_symmetric.html)
[Symmetric String Encryption (key based) ✔](java_string_encryption_key_based_symmetric.html)
[Symmetric File Encryption ✔](java_file_encryption_symmetric_password_based.html) |
+| Asymmetric Encryption / Public Key Cryptography | [Asymmetric String Encryption ✔](java_asymmetric_string_encryption.html) | |
+| Key Storage | |
+| Hashing | [String Hash ✔](java_string_hash.html) |
+| Crypto Provider Setup | |
+| Digital Signatures | [String Signing ✔](java_string_sign.html) |
diff --git a/java_string_encryption_asymmetric.md b/java_string_encryption_asymmetric.md
new file mode 100644
index 0000000..2c0d40c
--- /dev/null
+++ b/java_string_encryption_asymmetric.md
@@ -0,0 +1,51 @@
+---
+title: Java Asymmetric String Encryption using JDK
+keywords: sample
+summary: "Asymmetric String Encryption in Java"
+permalink: java_asymmetric_string_encryption.html
+folder: Java JDK
+references: [
+ # Place a list of references used to create and/or understand this example.
+ {
+ url: "https://docs.oracle.com/javase/10/docs/api/javax/crypto/Cipher.html",
+ description: "Java JDK Ciper"
+ }
+]
+authors: [
+ {
+ name: "Kai Mindermann",
+ url: "https://github.com/kmindi"
+ }
+]
+# List all reviewers that reviewed this version of the example. When the example is updated all old reviews
+# must be removed from the list below and the code has to be reviewed again. The complete review process
+# is documented in the main repository of CryptoExamples
+current_reviews: [
+
+]
+# Indicates when this example was last updated/created. Reviews don't change this.
+last_updated: "2020-02-16"
+tags: [Java, RSA, Asymmetric, String, Encryption]
+---
+
+## Use cases
+
+- Asymmetric encryption
+
+## Java version
+
+- openjdk8
+- oraclejdk9
+- openjdk9
+- oraclejdk11
+- openjdk11
+- oraclejdk13
+- openjdk13
+
+## Example Code for Java Asymmetric String Encryption using RSA 4096
+
+```java
+{% include_relative src/main/java/com/cryptoexamples/java/ExampleAsymmetricStringEncryption.java %}
+```
+
+{% include links.html %}
diff --git a/java_string_encryption_key_based_symmetric.md b/java_string_encryption_key_based_symmetric.md
index 9a36731..b2fc025 100644
--- a/java_string_encryption_key_based_symmetric.md
+++ b/java_string_encryption_key_based_symmetric.md
@@ -4,6 +4,27 @@ keywords: sample
summary: "String encryption in Java with key generation"
permalink: java_string_encryption_key_based_symmetric.html
folder: Java JDK
+references: [
+ # Place a list of references used to create and/or understand this example.
+ {
+ url: "https://docs.oracle.com/javase/10/docs/api/javax/crypto/Cipher.html",
+ description: "Oracle JDK Cipher Documentation"
+ }
+]
+authors: [
+ {
+ name: "Kai Mindermann",
+ url: "https://github.com/kmindi"
+ }
+]
+# List all reviewers that reviewed this version of the example. When the example is updated all old reviews
+# must be removed from the list below and the code has to be reviewed again. The complete review process
+# is documented in the main repository of CryptoExamples
+current_reviews: [
+
+]
+# Indicates when this example was last updated/created. Reviews don't change this.
+last_updated: "2020-02-16"
tags: [Java, AES, GCM, Salt, AEAD]
---
@@ -12,10 +33,20 @@ tags: [Java, AES, GCM, Salt, AEAD]
- Random key generation
- String encryption
-## Sample Code for Java based symmetric encryption using AES-GCM and generation of keys
+## Java version
+
+- openjdk8
+- oraclejdk9
+- openjdk9
+- oraclejdk11
+- openjdk11
+- oraclejdk13
+- openjdk13
+
+## Example Code for Java String Encryption with key generation using AES-GCM
```java
-{% include_relative src/main/java/com/cryptoexamples/java/ExampleStringEncryptionKeyBasedInOneMethod.java %}
+{% include_relative src/main/java/com/cryptoexamples/java/ExampleStringEncryptionKeyBased.java %}
```
diff --git a/java_string_encryption_password_based_symmetric.md b/java_string_encryption_password_based_symmetric.md
index b5de4ae..0e5ba9c 100644
--- a/java_string_encryption_password_based_symmetric.md
+++ b/java_string_encryption_password_based_symmetric.md
@@ -4,6 +4,27 @@ keywords: sample
summary: "Password based string encryption in Java"
permalink: java_string_encryption_password_based_symmetric.html
folder: Java JDK
+references: [
+ # Place a list of references used to create and/or understand this example.
+ {
+ url: "https://docs.oracle.com/javase/10/docs/api/javax/crypto/Cipher.html",
+ description: "Oracle JDK Cipher Documentation"
+ }
+]
+authors: [
+ {
+ name: "Kai Mindermann",
+ url: "https://github.com/kmindi"
+ }
+]
+# List all reviewers that reviewed this version of the example. When the example is updated all old reviews
+# must be removed from the list below and the code has to be reviewed again. The complete review process
+# is documented in the main repository of CryptoExamples
+current_reviews: [
+
+]
+# Indicates when this example was last updated/created. Reviews don't change this.
+last_updated: "2020-02-16"
tags: [Java, AES, GCM, PBKDF2, Salt, AEAD]
---
@@ -11,12 +32,21 @@ tags: [Java, AES, GCM, PBKDF2, Salt, AEAD]
- Password based encryption
- Previously shared common secret (password)
--
-## Sample Code for Java based symmetric encryption using AES-GCM and PBKDF2
+## Java version
+
+- openjdk8
+- oraclejdk9
+- openjdk9
+- oraclejdk11
+- openjdk11
+- oraclejdk13
+- openjdk13
+
+## Example Code for Java Password Based String Encryption using AES-GCM and PBKDF2
```java
-{% include_relative src/main/java/com/cryptoexamples/java/ExampleStringEncryptionPasswordBasedInOneMethod.java %}
+{% include_relative src/main/java/com/cryptoexamples/java/ExampleStringEncryptionPasswordBased.java %}
```
diff --git a/java_string_hash.md b/java_string_hash.md
index dbc9a80..08dbd49 100644
--- a/java_string_hash.md
+++ b/java_string_hash.md
@@ -4,17 +4,48 @@ keywords: sample
summary: "Java based string hashing"
permalink: java_string_hash.html
folder: Java JDK
+references: [
+ # Place a list of references used to create and/or understand this example.
+ {
+ url: "https://docs.oracle.com/javase/10/docs/api/java/security/MessageDigest.html",
+ description: "Oracle JDK MessageDigest Documentation"
+ }
+]
+authors: [
+ {
+ name: "Kai Mindermann",
+ url: "https://github.com/kmindi"
+ }
+]
+# List all reviewers that reviewed this version of the example. When the example is updated all old reviews
+# must be removed from the list below and the code has to be reviewed again. The complete review process
+# is documented in the main repository of CryptoExamples
+current_reviews: [
+
+]
+# Indicates when this example was last updated/created. Reviews don't change this.
+last_updated: "2020-02-16"
tags: [Java, hash, SHA, SHA-512]
---
## Use cases
-- verifying if a string has been changed
+- Verifying if a string has been changed
+
+## Java version
+
+- openjdk8
+- oraclejdk9
+- openjdk9
+- oraclejdk11
+- openjdk11
+- oraclejdk13
+- openjdk13
-## Sample Code for Java based hasing of a String using SHA-512, BASE64 and UTF-8 encoding
+## Example Code for Java String Hashing using SHA-512, BASE64 and UTF-8 encoding
```java
-{% include_relative src/main/java/com/cryptoexamples/java/ExampleHashInOneMethod.java %}
+{% include_relative src/main/java/com/cryptoexamples/java/ExampleHash.java %}
```
diff --git a/java_string_sign.md b/java_string_sign.md
index 446ed84..d4b2d74 100644
--- a/java_string_sign.md
+++ b/java_string_sign.md
@@ -4,6 +4,27 @@ keywords: sample
summary: "Java based string signing"
permalink: java_string_sign.html
folder: Java JDK
+references: [
+ # Place a list of references used to create and/or understand this example.
+ {
+ url: "https://docs.oracle.com/javase/10/docs/api/java/security/Signature.html",
+ description: "Oracle JDK Signature Documentation"
+ }
+]
+authors: [
+ {
+ name: "Kai Mindermann",
+ url: "https://github.com/kmindi"
+ }
+]
+# List all reviewers that reviewed this version of the example. When the example is updated all old reviews
+# must be removed from the list below and the code has to be reviewed again. The complete review process
+# is documented in the main repository of CryptoExamples
+current_reviews: [
+
+]
+# Indicates when this example was last updated/created. Reviews don't change this.
+last_updated: "2020-02-16"
tags: [Java, hash, SHA, SHA-512]
---
@@ -11,10 +32,20 @@ tags: [Java, hash, SHA, SHA-512]
- verifying if a string has been changed
-## Sample Code for Java based signing of a String using SHA-512, RSA 4096, BASE64 and UTF-8 encoding
+## Java version
+
+- openjdk8
+- oraclejdk9
+- openjdk9
+- oraclejdk11
+- openjdk11
+- oraclejdk13
+- openjdk13
+
+## Example Code for Java String Signing using SHA-512, RSA 4096, BASE64 and UTF-8 encoding
```java
-{% include_relative src/main/java/com/cryptoexamples/java/ExampleSignatureInOneMethod.java %}
+{% include_relative src/main/java/com/cryptoexamples/java/ExampleSignature.java %}
```
diff --git a/src/main/java/com/cryptoexamples/java/EncryptedFile.java b/src/main/java/com/cryptoexamples/java/EncryptedFile.java
deleted file mode 100644
index e2b894d..0000000
--- a/src/main/java/com/cryptoexamples/java/EncryptedFile.java
+++ /dev/null
@@ -1,194 +0,0 @@
-package com.cryptoexamples.java;
-
-import javax.crypto.*;
-import javax.crypto.spec.GCMParameterSpec;
-import javax.crypto.spec.PBEKeySpec;
-import javax.crypto.spec.SecretKeySpec;
-import java.io.*;
-import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.spec.KeySpec;
-import java.util.Base64;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Encapsulating class for saving a String encrypted in a file and to decrypt/retrieve it.
- *
- * Including
- * - Random password generation using strong secure random number generator
- * - Random salt generation
- * - Key derivation using PBKDF2 HMAC SHA-256,
- * - AES-256 authenticated encryption using GCM
- * - UTF-8 encoding
- * // TODO store all encryption parameters (as authenticated data) prepended to the file content
- * // TODO use Cryptographic Message Snytax (https://tools.ietf.org/html/rfc5652)
- */
-public class EncryptedFile implements Serializable {
- private static final Logger LOGGER = Logger.getLogger(EncryptedFile.class.getName());
-
- /* 128, 120, 112, 104, or 96 @see NIST Special Publication 800-38D*/
- private static final int DEFAULT_GCM_AUTHENTICATION_TAG_SIZE_BITS = 128;
-
- private static final int DEFAULT_GCM_IV_NONCE_SIZE_BYTES = 12;
- private static final int DEFAULT_PBKDF2_ITERATIONS = 65536;
- private static final int DEFAULT_PBKDF2_SALT_SIZE_BYTES = 32;
-
- /* @see https://www.keylength.com/ */
- private static final int DEFAULT_AES_KEY_LENGTH_BITS = 256;
- private static final String DEFAULT_CIPHER = "AES";
- private static final String DEFAULT_CIPHERSCHEME = "AES/GCM/NoPadding";
- private static final String DEFAULT_PBKDF2_SCHEME = "PBKDF2WithHmacSHA256";
-
- private int gcmAuthenticationTagSizeBits = DEFAULT_GCM_AUTHENTICATION_TAG_SIZE_BITS;
- private int gcmIvNonceSizeBytes = DEFAULT_GCM_IV_NONCE_SIZE_BYTES;
- private int pbkdf2Iterations = DEFAULT_PBKDF2_ITERATIONS;
- private int pbkdf2SaltSizeBytes = DEFAULT_PBKDF2_SALT_SIZE_BYTES;
- private int aesKeyLengthBits = DEFAULT_AES_KEY_LENGTH_BITS;
- private String cipher = DEFAULT_CIPHER;
- private String cipherscheme = DEFAULT_CIPHERSCHEME;
- private String pbkdf2Scheme = DEFAULT_PBKDF2_SCHEME;
-
- /**
- * Creates a new empty EncryptedFile object
- */
- public EncryptedFile() {
- // uses default parameters, see initialization at the beginning.
- }
-
- /**
- * Generates a randomly filled byte array
- *
- * @param sizeInBytes length of the array in bytes
- * @return byte array containing random values
- * @throws NoSuchAlgorithmException
- */
- private static byte[] generateRandomArry(int sizeInBytes) throws NoSuchAlgorithmException {
- /* generate random salt */
- final byte[] salt = new byte[sizeInBytes];
- SecureRandom random = SecureRandom.getInstanceStrong();
- random.nextBytes(salt);
- return salt;
- }
-
- /**
- * Generates a random password.
- *
- * @param sizeInBytes length of the password in byte
- * @return Base64 encoded string with a random password
- * @throws NoSuchAlgorithmException
- */
- public static String generatePassword(int sizeInBytes) throws NoSuchAlgorithmException {
- return Base64.getEncoder().encodeToString(generateRandomArry(sizeInBytes));
- }
-
- /**
- * Encrypts the provided plainText using the provided password and stores it in a file
- *
- * @param plainText plaintext that should be encrypted
- * @param password password which is used to generate the key
- * @param path path to a writeable file (may already exist)
- * @throws GeneralSecurityException
- */
- public void encrypt(String plainText, String password, String path) throws GeneralSecurityException {
- /* Derive the key*/
- SecretKeyFactory factory = SecretKeyFactory.getInstance(pbkdf2Scheme);
- byte[] newSalt = generateRandomArry(pbkdf2SaltSizeBytes);
- KeySpec keyspec = new PBEKeySpec(password.toCharArray(), newSalt, pbkdf2Iterations, aesKeyLengthBits);
- SecretKey tmp = factory.generateSecret(keyspec);
- SecretKey key = new SecretKeySpec(tmp.getEncoded(), cipher);
-
- Cipher myCipher = Cipher.getInstance(cipherscheme);
- byte[] newNonce = generateRandomArry(gcmIvNonceSizeBytes);
- GCMParameterSpec spec = new GCMParameterSpec(gcmAuthenticationTagSizeBits, newNonce);
- myCipher.init(Cipher.ENCRYPT_MODE, key, spec);
-
- // SET UP OUTPUT STREAM and write content of String
- try (
- FileOutputStream fileOutputStream = new FileOutputStream(path);
- CipherOutputStream encryptedOutputStream = new CipherOutputStream(fileOutputStream, myCipher);
- InputStream stringInputStream = new ByteArrayInputStream(plainText.getBytes(StandardCharsets.UTF_8));
- ) {
- // write IV/nonce
- fileOutputStream.write(newNonce);
-
- // write salt
- fileOutputStream.write(newSalt);
-
- byte[] buffer = new byte[8192];
- while (stringInputStream.read(buffer) > 0) {
- encryptedOutputStream.write(buffer);
- }
- } catch (IOException e) {
- LOGGER.log(Level.SEVERE, e.getMessage(), e);
- throw new SecurityException(e.getMessage(), e);
- }
- }
-
- /**
- * Decrypts the cipherText using the provided password.
- *
- * @param password password which is used to generate the key
- * @param path path to a previously encrypted file to be decrypted
- * @return plaintext
- * @throws GeneralSecurityException
- */
- public String decrypt(String password, String path ) throws GeneralSecurityException {
-
- // Read configuration from file
-
- byte[] myNonce = new byte[gcmIvNonceSizeBytes];
- byte[] mySalt = new byte[pbkdf2SaltSizeBytes];
-
- try (
- FileInputStream fileInputStream = new FileInputStream(path);
- ) {
- int countReadBytesNonce = fileInputStream.read(myNonce);
- int countReadBytesSalt = fileInputStream.read(mySalt);
- } catch (IOException e) {
- LOGGER.log(Level.SEVERE, e.getMessage(), e);
- throw new SecurityException(e.getMessage(), e);
- }
-
- /* Derive the key*/
- SecretKeyFactory factory = SecretKeyFactory.getInstance(pbkdf2Scheme);
- // Needs unlimited strength policy files http://www.oracle.com/technetwork/java/javase/downloads
- KeySpec keyspec = new PBEKeySpec(password.toCharArray(), mySalt, pbkdf2Iterations, aesKeyLengthBits);
- SecretKey tmp = factory.generateSecret(keyspec);
- SecretKey key = new SecretKeySpec(tmp.getEncoded(), cipher);
-
- Cipher myCipher = Cipher.getInstance(cipherscheme);
- GCMParameterSpec spec = new GCMParameterSpec(gcmAuthenticationTagSizeBits, myNonce);
-
- myCipher.init(Cipher.DECRYPT_MODE, key, spec);
-
- // READ ENCRYPTED FILE
- StringBuilder stringBuilder = new StringBuilder();
-
- //cipher.updateAAD(aad);
- try (
- FileInputStream fileInputStream = new FileInputStream(path);
- CipherInputStream cipherInputStream = new CipherInputStream(fileInputStream, myCipher);
- ) {
- // offset the stream by the bytes already read previosly
-
- // TODO check if file has this bytes at least.
- byte[] skipped = new byte[gcmIvNonceSizeBytes+pbkdf2SaltSizeBytes];
- int read = fileInputStream.read(skipped);
-
- byte[] buffer = new byte[8192];
- while (cipherInputStream.read(buffer) > 0) {
- stringBuilder.append(new String(buffer, StandardCharsets.UTF_8));
- }
- } catch (IOException e) {
- LOGGER.log(Level.SEVERE, e.getMessage(), e);
- throw new SecurityException(e.getMessage(), e);
- }
-
- // TODO trim() should not be needed!
- return stringBuilder.toString().trim();
- }
-}
-
diff --git a/src/main/java/com/cryptoexamples/java/EncryptedString.java b/src/main/java/com/cryptoexamples/java/EncryptedString.java
deleted file mode 100644
index fd1b7b9..0000000
--- a/src/main/java/com/cryptoexamples/java/EncryptedString.java
+++ /dev/null
@@ -1,188 +0,0 @@
-package com.cryptoexamples.java;
-
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.spec.GCMParameterSpec;
-import javax.crypto.spec.PBEKeySpec;
-import javax.crypto.spec.SecretKeySpec;
-import java.io.Serializable;
-import java.security.GeneralSecurityException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.spec.KeySpec;
-import java.util.Base64;
-
-/**
- * Encapsulating class for encrypting and decrypting strings
- * Including
- * - Random password generation using strong secure random number generator
- * - Random salt generation
- * - Key derivation using PBKDF2 HMAC SHA-256,
- * - AES-256 authenticated encryption using GCM
- * - BASE64-encoding as representation for the byte-arrays
- */
-public class EncryptedString implements Serializable {
-
- /* 128, 120, 112, 104, or 96 @see NIST Special Publication 800-38D*/
- private static final int DEFAULT_GCM_AUTHENTICATION_TAG_SIZE_BITS = 128;
-
- private static final int DEFAULT_GCM_IV_NONCE_SIZE_BYTES = 12;
- private static final int DEFAULT_PBKDF2_ITERATIONS = 65536;
- private static final int DEFAULT_PBKDF2_SALT_SIZE_BYTES = 32;
-
- /* @see https://www.keylength.com/ */
- private static final int DEFAULT_AES_KEY_LENGTH_BITS = 256;
- private static final String DEFAULT_CIPHER = "AES";
- private static final String DEFAULT_CIPHERSCHEME = "AES/GCM/NoPadding";
- private static final String DEFAULT_PBKDF2_SCHEME = "PBKDF2WithHmacSHA256";
-
- private int gcmAuthenticationTagSizeBits = DEFAULT_GCM_AUTHENTICATION_TAG_SIZE_BITS;
- private int gcmIvNonceSizeBytes = DEFAULT_GCM_IV_NONCE_SIZE_BYTES;
- private int pbkdf2Iterations = DEFAULT_PBKDF2_ITERATIONS;
- private int pbkdf2SaltSizeBytes = DEFAULT_PBKDF2_SALT_SIZE_BYTES;
- private int aesKeyLengthBits = DEFAULT_AES_KEY_LENGTH_BITS;
- private String cipher = DEFAULT_CIPHER;
- private String cipherscheme = DEFAULT_CIPHERSCHEME;
- private String pbkdf2Scheme = DEFAULT_PBKDF2_SCHEME;
-
- private byte[] nonce;
- private byte[] salt;
- private String cipherText;
-
- /**
- * Creates a new com.cryptoexamples.java.EncryptedString object based on cipherText, nonce and salt.
- *
- * @param cipherText encrypted plaintext (generated from encrypt)
- * @param nonce byte array, number used once (random) see gcmIvNonceSizeBytes
- * @param salt random byte array to prevent rainbow table attacks on password lists
- */
- public EncryptedString(String cipherText, byte[] nonce, byte[] salt) {
- this.cipherText = cipherText;
- this.nonce = nonce;
- this.salt = salt;
- }
-
- /**
- * Initializes this com.cryptoexamples.java.EncryptedString object with the provided parameters
- *
- * @param cipher
- * @param cipherscheme
- * @param gcmAuthenticationTagSizeBits
- * @param gcmIvNonceSizeBytes
- * @param pbkdf2Iterations
- * @param pbkdf2SaltSizeBytes
- * @param aesKeyLengthBits
- * @param pbkdf2Scheme
- */
- private EncryptedString(String cipherText, byte[] nonce, byte[] salt, String cipher, String cipherscheme, int gcmAuthenticationTagSizeBits, int gcmIvNonceSizeBytes, int pbkdf2Iterations, int pbkdf2SaltSizeBytes, int aesKeyLengthBits, String pbkdf2Scheme) {
- this.cipherText = cipherText;
- this.nonce = nonce;
- this.salt = salt;
-
- this.cipher = cipher;
- this.cipherscheme = cipherscheme;
- this.gcmAuthenticationTagSizeBits = gcmAuthenticationTagSizeBits;
- this.gcmIvNonceSizeBytes = gcmIvNonceSizeBytes;
- this.pbkdf2Iterations = pbkdf2Iterations;
- this.pbkdf2SaltSizeBytes = pbkdf2SaltSizeBytes;
- this.aesKeyLengthBits = aesKeyLengthBits;
- this.pbkdf2Scheme = pbkdf2Scheme;
- }
-
- /**
- * Creates a new empty com.cryptoexamples.java.EncryptedString object
- */
- public EncryptedString() {
- // uses default parameters, see initialization at the beginning.
- }
-
- /**
- * Generates a randomly filled byte array
- *
- * @param sizeInBytes length of the array in bytes
- * @return byte array containing random values
- * @throws NoSuchAlgorithmException
- */
- private static byte[] generateRandomArry(int sizeInBytes) throws NoSuchAlgorithmException {
- /* generate random salt */
- final byte[] salt = new byte[sizeInBytes];
- SecureRandom random = SecureRandom.getInstanceStrong();
- random.nextBytes(salt);
- return salt;
- }
-
- /**
- * Generates a random password.
- *
- * @param sizeInBytes length of the password in byte
- * @return Base64 encoded string with a random password
- * @throws NoSuchAlgorithmException
- */
- public static String generatePassword(int sizeInBytes) throws NoSuchAlgorithmException {
- return Base64.getEncoder().encodeToString(generateRandomArry(sizeInBytes));
- }
-
- private byte[] getNonce() {
- return this.nonce;
- }
-
- private byte[] getSalt() {
- return this.salt;
- }
-
- private String getCipherText() {
- return this.cipherText;
- }
-
- /**
- * Encrypts the provided plainText using the provided password.
- *
- * @param plainText plaintext that should be encrypted
- * @param password password which is used to generate the key
- * @return new com.cryptoexamples.java.EncryptedString object
- * @throws GeneralSecurityException
- */
- public EncryptedString encrypt(String plainText, String password) throws GeneralSecurityException {
- /* Derive the key*/
- SecretKeyFactory factory = SecretKeyFactory.getInstance(pbkdf2Scheme);
- byte[] newSalt = generateRandomArry(pbkdf2SaltSizeBytes);
- KeySpec keyspec = new PBEKeySpec(password.toCharArray(), newSalt, pbkdf2Iterations, aesKeyLengthBits);
- SecretKey tmp = factory.generateSecret(keyspec);
- SecretKey key = new SecretKeySpec(tmp.getEncoded(), cipher);
-
- Cipher myCipher = Cipher.getInstance(cipherscheme);
- byte[] newNonce = generateRandomArry(gcmIvNonceSizeBytes);
- GCMParameterSpec spec = new GCMParameterSpec(gcmAuthenticationTagSizeBits, newNonce);
- myCipher.init(Cipher.ENCRYPT_MODE, key, spec);
-
- byte[] byteCipher = myCipher.doFinal(plainText.getBytes());
-
- return new EncryptedString(new String(Base64.getEncoder().encode(byteCipher)), newNonce, newSalt, this.cipher, cipherscheme, gcmAuthenticationTagSizeBits, gcmIvNonceSizeBytes, pbkdf2Iterations, pbkdf2SaltSizeBytes, aesKeyLengthBits, pbkdf2Scheme);
- }
-
- /**
- * Decrypts the cipherText using the provided password.
- *
- * @param password password which is used to generate the key
- * @return plaintext
- * @throws GeneralSecurityException
- */
- public String decrypt(String password) throws GeneralSecurityException {
- /* Derive the key*/
- SecretKeyFactory factory = SecretKeyFactory.getInstance(pbkdf2Scheme);
- // Needs unlimited strength policy files http://www.oracle.com/technetwork/java/javase/downloads
- KeySpec keyspec = new PBEKeySpec(password.toCharArray(), getSalt(), pbkdf2Iterations, aesKeyLengthBits);
- SecretKey tmp = factory.generateSecret(keyspec);
- SecretKey key = new SecretKeySpec(tmp.getEncoded(), cipher);
-
- Cipher myCipher = Cipher.getInstance(cipherscheme);
- GCMParameterSpec spec = new GCMParameterSpec(gcmAuthenticationTagSizeBits, getNonce());
-
- myCipher.init(Cipher.DECRYPT_MODE, key, spec);
-
- byte[] decryptedCipher = myCipher.doFinal(Base64.getDecoder().decode(getCipherText()));
- return new String(decryptedCipher);
- }
-}
-
diff --git a/src/main/java/com/cryptoexamples/java/ExampleAsymmetricStringEncryption.java b/src/main/java/com/cryptoexamples/java/ExampleAsymmetricStringEncryption.java
new file mode 100644
index 0000000..b5c84c3
--- /dev/null
+++ b/src/main/java/com/cryptoexamples/java/ExampleAsymmetricStringEncryption.java
@@ -0,0 +1,55 @@
+package com.cryptoexamples.java;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import java.nio.charset.StandardCharsets;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.util.Base64;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Example for asymmetric encryption and decryption of a string in one method.
+ * - Generation of public and private RSA 4096 bit keypair
+ * - BASE64 encoding as representation for the byte-arrays
+ * - UTF-8 encoding of Strings
+ * - Exception handling
+ */
+public class ExampleAsymmetricStringEncryption {
+ private static final Logger LOGGER = Logger.getLogger(ExampleAsymmetricStringEncryption.class.getName());
+
+ public static void main(String[] args) {
+ String plainText = "Text that is going to be sent over an insecure channel and must be encrypted at all costs!";
+ try {
+ // GENERATE NEW KEYPAIR
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
+ /* @see https://www.keylength.com/ */
+ keyPairGenerator.initialize(4096);
+ KeyPair keyPair = keyPairGenerator.generateKeyPair();
+
+ // ENCRYPTION
+ Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
+ cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
+
+ byte[] cipherTextBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
+
+ // CONVERSION of raw bytes to BASE64 representation
+ String cipherText = Base64.getEncoder().encodeToString(cipherTextBytes);
+
+ // DECRYPTION
+ cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
+ byte[] decryptedCipherTextBytes = cipher.doFinal(Base64.getDecoder().decode(cipherText));
+ String decryptedCipherText = new String(decryptedCipherTextBytes,StandardCharsets.UTF_8);
+
+ LOGGER.log(Level.INFO, () -> String.format("Decrypted and original plain text are the same: %b", decryptedCipherText.compareTo(plainText) == 0));
+ } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidParameterException e) {
+ LOGGER.log(Level.SEVERE, e.getLocalizedMessage());
+ }
+ }
+}
diff --git a/src/main/java/com/cryptoexamples/java/ExampleEncryptedFile.java b/src/main/java/com/cryptoexamples/java/ExampleEncryptedFile.java
deleted file mode 100644
index b45eeb6..0000000
--- a/src/main/java/com/cryptoexamples/java/ExampleEncryptedFile.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.cryptoexamples.java;
-
-import java.security.GeneralSecurityException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-// TODO check if KeyStore should be used
-
-/**
- * Object oriented example for encryption and decryption of a string;
- * Including
- * - Random password generation using strong secure random number generator
- * - Random salt generation
- * - Key derivation using PBKDF2 HMAC SHA-256,
- * - AES-256 authenticated encryption using GCM
- * - BASE64-encoding as representation for the byte-arrays
- * - Exception handling
- */
-public class ExampleEncryptedFile {
- private static final Logger LOGGER = Logger.getLogger(ExampleEncryptedFile.class.getName());
-
- public static void main(String[] args) {
- String plainText = "Text that is going to be sent over an insecure channel and must be encrypted at all costs!";
-
- try {
- // GENERATE a password (if a password exists, use that).
- String password = EncryptedFile.generatePassword(32);
- String path = "encryptedFile.enc";
-
-
- // ENCRYPTION
- new EncryptedFile().encrypt(plainText, password, path);
-
- // DECRYPTION
- String decryptedCipherText = new EncryptedFile().decrypt(password, path);
-
- LOGGER.log(Level.INFO, () -> String.format("Decrypted and original plain text are the same: %b", decryptedCipherText.compareTo(plainText) == 0));
- } catch (GeneralSecurityException e) {
- LOGGER.log(Level.SEVERE, e.getMessage(), e);
- }
- }
-
-}
diff --git a/src/main/java/com/cryptoexamples/java/ExampleEncryptedString.java b/src/main/java/com/cryptoexamples/java/ExampleEncryptedString.java
deleted file mode 100644
index 2d30af1..0000000
--- a/src/main/java/com/cryptoexamples/java/ExampleEncryptedString.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.cryptoexamples.java;
-
-import java.security.GeneralSecurityException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-// TODO check if KeyStore should be used
-
-/**
- * Object oriented example for encryption and decryption of a string;
- * Including
- * - Random password generation using strong secure random number generator
- * - random salt generation
- * - Key derivation using PBKDF2 HMAC SHA-256,
- * - AES-256 authenticated encryption using GCM
- * - BASE64-encoding as representation for the byte-arrays
- * - Exception handling
- */
-public class ExampleEncryptedString {
- private static final Logger LOGGER = Logger.getLogger(ExampleEncryptedString.class.getName());
-
- public static void main(String[] args) {
- String plainText = "Text that is going to be sent over an insecure channel and must be encrypted at all costs!";
-
- try {
- // GENERATE a password (if a password exists, use that).
- String password = EncryptedString.generatePassword(32);
-
- // ENCRYPTION
- EncryptedString encryptedString = new EncryptedString().encrypt(plainText, password);
-
- // DECRYPTION
- String decryptedCipherText = encryptedString.decrypt(password);
-
- LOGGER.log(Level.INFO, () -> String.format("Decrypted and original plain text are the same: %b", decryptedCipherText.compareTo(plainText) == 0));
- } catch (GeneralSecurityException e) {
- LOGGER.log(Level.SEVERE, e.getMessage(), e);
- }
- }
-
-}
diff --git a/src/main/java/com/cryptoexamples/java/ExampleFileEncryption.java b/src/main/java/com/cryptoexamples/java/ExampleFileEncryption.java
new file mode 100644
index 0000000..d1404db
--- /dev/null
+++ b/src/main/java/com/cryptoexamples/java/ExampleFileEncryption.java
@@ -0,0 +1,127 @@
+package com.cryptoexamples.java;
+
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+import javax.crypto.CipherOutputStream;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.security.*;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.util.Base64;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Example for encryption and decryption of a file in one method.
+ * - Random password generation using strong secure random number generator
+ * - Random salt generation
+ * - Key derivation using PBKDF2 HMAC SHA-512,
+ * - AES-256 authenticated encryption using GCM
+ * - BASE64-encoding as representation for the byte-arrays
+ * - Exception handling
+ */
+public class ExampleFileEncryption {
+ private static final Logger LOGGER = Logger.getLogger(ExampleFileEncryption.class.getName());
+
+ /**
+ * Demonstrational method that encrypts a file using a password (that is used to derive the required key).
+ * @param fileName
+ * @param plainText
+ * @param password
+ * @return true if encryption and decryption were successful, false otherwise
+ */
+ public static boolean demonstrateFileEncryption(String fileName, String plainText, String password) {
+ try {
+ // GENERATE password (not needed if you have a password already)
+ if(password == null || password.isEmpty()) {
+ KeyGenerator keyGen = KeyGenerator.getInstance("AES");
+ keyGen.init(256);
+ password = Base64.getEncoder().encodeToString(keyGen.generateKey().getEncoded());
+ }
+
+ // GENERATE random salt
+ final byte[] salt = new byte[64];
+ SecureRandom random = SecureRandom.getInstanceStrong();
+ random.nextBytes(salt);
+
+ // DERIVE key (from password and salt)
+ SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
+ KeySpec passwordBasedEncryptionKeySpec = new PBEKeySpec(password.toCharArray(), salt, 10000, 256);
+ SecretKey secretKeyFromPBKDF2 = secretKeyFactory.generateSecret(passwordBasedEncryptionKeySpec);
+ SecretKey key = new SecretKeySpec(secretKeyFromPBKDF2.getEncoded(), "AES");
+
+ // GENERATE random nonce (number used once)
+ final byte[] nonce = new byte[32];
+ random.nextBytes(nonce);
+
+ // SET UP CIPHER for encryption
+ Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
+ GCMParameterSpec spec = new GCMParameterSpec(16 * 8, nonce);
+ cipher.init(Cipher.ENCRYPT_MODE, key, spec);
+
+ // TODO store encryption parameters as authenticated data prepended to the file content
+
+ // SET UP OUTPUT STREAM and write content of String
+ try (
+ FileOutputStream fileOutputStream = new FileOutputStream(fileName);
+ CipherOutputStream encryptedOutputStream = new CipherOutputStream(fileOutputStream, cipher);
+ InputStream stringInputStream = new ByteArrayInputStream(plainText.getBytes(StandardCharsets.UTF_8))
+ ) {
+ byte[] buffer = new byte[8192];
+ int nread;
+ while ((nread = stringInputStream.read(buffer)) > 0) {
+ encryptedOutputStream.write(buffer, 0, nread);
+ }
+ encryptedOutputStream.flush();
+ }
+
+ // READ ENCRYPTED FILE
+ StringBuilder stringBuilder = new StringBuilder();
+ cipher.init(Cipher.DECRYPT_MODE, key, spec);
+ String decryptedCipherText;
+ try (
+ FileInputStream fileInputStream = new FileInputStream(fileName);
+ CipherInputStream cipherInputStream = new CipherInputStream(fileInputStream, cipher);
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ ) {
+ byte[] buffer = new byte[8192];
+ int nread;
+ while ((nread = cipherInputStream.read(buffer)) > 0) {
+ byteArrayOutputStream.write(buffer, 0, nread);
+ }
+ byteArrayOutputStream.flush();
+ decryptedCipherText = new String(byteArrayOutputStream.toByteArray(), StandardCharsets.UTF_8);
+ }
+
+ LOGGER.log(Level.INFO, decryptedCipherText);
+ LOGGER.log(Level.INFO,
+ () -> String.format("Decrypted file content and original plain text are the same: %b",
+ decryptedCipherText.compareTo(plainText) == 0)
+ );
+ return decryptedCipherText.compareTo(plainText) == 0;
+ } catch (NoSuchAlgorithmException |
+ NoSuchPaddingException |
+ InvalidKeyException |
+ InvalidParameterException |
+ InvalidAlgorithmParameterException |
+ InvalidKeySpecException |
+ IOException e) {
+ LOGGER.log(Level.SEVERE, e.getLocalizedMessage());
+ return false;
+ }
+ }
+
+
+ public static void main(String[] args) {
+ demonstrateFileEncryption("encryptedFile.enc","Multiline text:\nMultiline text:\n",null );
+ }
+
+}
diff --git a/src/main/java/com/cryptoexamples/java/ExampleFileEncryptionInOneMethod.java b/src/main/java/com/cryptoexamples/java/ExampleFileEncryptionInOneMethod.java
deleted file mode 100644
index ef89604..0000000
--- a/src/main/java/com/cryptoexamples/java/ExampleFileEncryptionInOneMethod.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package com.cryptoexamples.java;
-
-import javax.crypto.*;
-import javax.crypto.spec.GCMParameterSpec;
-import javax.crypto.spec.PBEKeySpec;
-import javax.crypto.spec.SecretKeySpec;
-import java.io.*;
-import java.nio.charset.StandardCharsets;
-import java.security.*;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-import java.util.Base64;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * All in one example for encryption and decryption of a file in one method;
- * Including
- * - Random password generation using strong secure random number generator
- * - Random salt generation
- * - Key derivation using PBKDF2 HMAC SHA-256,
- * - AES-256 authenticated encryption using GCM
- * - BASE64-encoding as representation for the byte-arrays
- * - Exception handling
- */
-public class ExampleFileEncryptionInOneMethod {
- private static final Logger LOGGER = Logger.getLogger(ExampleFileEncryptionInOneMethod.class.getName());
-
- public static void main(String[] args) {
- String plainText = "Multiline text:";
- try {
- // GENERATE password
- KeyGenerator keyGen = KeyGenerator.getInstance("AES");
- // Needs unlimited strength policy files http://www.oracle.com/technetwork/java/javase/downloads
- keyGen.init(256);
- String password = Base64.getEncoder().encodeToString(keyGen.generateKey().getEncoded());
-
- // GENERATE random salt
- final byte[] salt = new byte[12];
- SecureRandom random = SecureRandom.getInstanceStrong();
- random.nextBytes(salt);
-
- // DERIVE key (from password and salt)
- SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
- // Needs unlimited strength policy files http://www.oracle.com/technetwork/java/javase/downloads
- KeySpec keyspec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256);
- SecretKey tmp = factory.generateSecret(keyspec);
- SecretKey key = new SecretKeySpec(tmp.getEncoded(), "AES");
-
- // GENERATE random nonce (number used once)
- final byte[] nonce = new byte[32];
- random.nextBytes(nonce);
-
- // SET UP CIPHER for encryption
- Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
- GCMParameterSpec spec = new GCMParameterSpec(16 * 8, nonce);
- cipher.init(Cipher.ENCRYPT_MODE, key, spec);
-
- //byte[] aad = "Additional authenticated not encrypted data".getBytes();
- //cipher.updateAAD(aad);
-
- // TODO store encryption parameters as authenticated data prepended to the file content
-
- // SET UP OUTPUT STREAM and write content of String
- try (
- FileOutputStream fileOutputStream = new FileOutputStream("encryptedFile.enc");
- CipherOutputStream encryptedOutputStream = new CipherOutputStream(fileOutputStream, cipher);
- InputStream stringInputStream = new ByteArrayInputStream(plainText.getBytes(StandardCharsets.UTF_8));
- ) {
- byte[] buffer = new byte[8192];
- while (stringInputStream.read(buffer) > 0) {
- encryptedOutputStream.write(buffer);
- }
- }
-
- // READ ENCRYPTED FILE
- StringBuilder stringBuilder = new StringBuilder();
- cipher.init(Cipher.DECRYPT_MODE, key, spec);
- //cipher.updateAAD(aad);
- try (
- FileInputStream fileInputStream = new FileInputStream("encryptedFile.enc");
- CipherInputStream cipherInputStream = new CipherInputStream(fileInputStream, cipher);
- ) {
- byte[] buffer = new byte[8192];
- while (cipherInputStream.read(buffer) > 0) {
- stringBuilder.append(new String(buffer, StandardCharsets.UTF_8));
- }
- }
- // TODO trim() should not be needed!
- String decryptedCipherText = stringBuilder.toString().trim();
- LOGGER.log(Level.INFO, decryptedCipherText);
-
- LOGGER.log(Level.INFO,
- () -> String.format("Decrypted file content and original plain text are the same: %b",
- decryptedCipherText.compareTo(plainText) == 0)
- );
- } catch (NoSuchAlgorithmException |
- NoSuchPaddingException |
- InvalidKeyException |
- InvalidParameterException |
- InvalidAlgorithmParameterException |
- InvalidKeySpecException |
- IOException e) {
- LOGGER.log(Level.SEVERE, e.getMessage(), e);
- }
- }
-
-}
diff --git a/src/main/java/com/cryptoexamples/java/ExampleHash.java b/src/main/java/com/cryptoexamples/java/ExampleHash.java
new file mode 100644
index 0000000..5a20e0a
--- /dev/null
+++ b/src/main/java/com/cryptoexamples/java/ExampleHash.java
@@ -0,0 +1,48 @@
+package com.cryptoexamples.java;
+
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Base64;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Example for hashing of a string in one method.
+ * - SHA-512
+ * - BASE64 encoding as representation for the byte-arrays
+ * - UTF-8 encoding of String
+ * - Exception handling
+ */
+public class ExampleHash {
+ private static final Logger LOGGER = Logger.getLogger(ExampleHash.class.getName());
+
+ /**
+ * Demonstrational method that hashes the plainText.
+ * @param plainText
+ * @return true if hashing was successful, false otherwise
+ */
+ public static boolean demonstrateHash(String plainText) {
+ try {
+ // Get MessageDigest Instance
+ MessageDigest messageDigest = MessageDigest.getInstance("SHA-512");
+
+ // CREATE HASH
+ byte[] hashBytes = messageDigest.digest(plainText.getBytes(StandardCharsets.UTF_8));
+
+ // CONVERT/ENCODE IN BASE64
+ String hashString = Base64.getEncoder().encodeToString(hashBytes);
+
+ LOGGER.log(Level.INFO, hashString);
+ return true;
+ } catch (NoSuchAlgorithmException e) {
+ LOGGER.log(Level.SEVERE, e.getLocalizedMessage());
+ return false;
+ }
+ }
+
+ public static void main(String[] args) {
+ demonstrateHash("Text that should be authenticated by comparing the hash of it!");
+ }
+}
diff --git a/src/main/java/com/cryptoexamples/java/ExampleHashInOneMethod.java b/src/main/java/com/cryptoexamples/java/ExampleHashInOneMethod.java
deleted file mode 100644
index c3b15d7..0000000
--- a/src/main/java/com/cryptoexamples/java/ExampleHashInOneMethod.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.cryptoexamples.java;
-
-
-import java.nio.charset.StandardCharsets;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Base64;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * All in one example for hashing of a string in one method;
- * Including
- * - SHA-512
- * - BASE64-encoding as representation for the byte-arrays
- * - UTF-8 encoding of String
- * - Exception handling
- */
-public class ExampleHashInOneMethod {
- private static final Logger LOGGER = Logger.getLogger(ExampleHashInOneMethod.class.getName());
-
- public static void main(String[] args) {
- String plainText = "Text that should be authenticated by comparing the hash of it!";
- try {
- // https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#MessageDigest
- MessageDigest messageDigest = MessageDigest.getInstance("SHA-512");
-
- // CREATE HASH
- byte[] hash = messageDigest.digest(plainText.getBytes(StandardCharsets.UTF_8));
-
- // CONVERT/ENCODE IN BASE64
- String hashString = new String(Base64.getEncoder().encode(hash),StandardCharsets.UTF_8);
-
- LOGGER.log(Level.INFO, hashString);
- } catch (NoSuchAlgorithmException e) {
- LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
- }
- }
-}
diff --git a/src/main/java/com/cryptoexamples/java/ExampleSignatureInOneMethod.java b/src/main/java/com/cryptoexamples/java/ExampleSignature.java
similarity index 65%
rename from src/main/java/com/cryptoexamples/java/ExampleSignatureInOneMethod.java
rename to src/main/java/com/cryptoexamples/java/ExampleSignature.java
index ddb3306..1ad54f0 100644
--- a/src/main/java/com/cryptoexamples/java/ExampleSignatureInOneMethod.java
+++ b/src/main/java/com/cryptoexamples/java/ExampleSignature.java
@@ -12,19 +12,22 @@
import java.util.logging.Logger;
/**
- * All in one example for cryptographic signing of a string in one method;
- * Including
+ * Example for cryptographic signing of a string in one method.
* - Generation of public and private RSA 4096 bit keypair
* - SHA-512 with RSA
- * - BASE64-encoding as representation for the byte-arrays
+ * - BASE64 encoding as representation for the byte-arrays
* - UTF-8 encoding of String
* - Exception handling
*/
-public class ExampleSignatureInOneMethod {
- private static final Logger LOGGER = Logger.getLogger(ExampleSignatureInOneMethod.class.getName());
+public class ExampleSignature {
+ private static final Logger LOGGER = Logger.getLogger(ExampleSignature.class.getName());
- public static void main(String[] args) {
- String plainText = "Text that should be signed to prevent unknown tampering with its content.";
+ /**
+ * Demonstrational method that signs the plainText using a newly generated keypair.
+ * @param plainText
+ * @return true if signing and verification were successful, false otherwise
+ */
+ public static boolean demonstrateSignature(String plainText) {
try {
// GENERATE NEW KEYPAIR
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
@@ -38,18 +41,24 @@ public static void main(String[] args) {
signature.update(plainText.getBytes(StandardCharsets.UTF_8));
// SIGN DATA/STRING
- byte[] signatureForPlainText = signature.sign();
- String signatureForPlainTextString = new String(Base64.getEncoder().encode(signatureForPlainText),StandardCharsets.UTF_8);
+ String signatureForPlainTextString = Base64.getEncoder().encodeToString(signature.sign());
LOGGER.log(Level.INFO, () -> String.format("Signature: %s", signatureForPlainTextString));
// VERIFY JUST CREATED SIGNATURE USING PUBLIC KEY
signature.initVerify(keyPair.getPublic());
signature.update(plainText.getBytes(StandardCharsets.UTF_8));
- boolean isSignatureCorrect = signature.verify(signatureForPlainText);
+ boolean isSignatureCorrect = signature.verify(Base64.getDecoder().decode(signatureForPlainTextString));
LOGGER.log(Level.INFO, () -> String.format("Signature is correct: %b", isSignatureCorrect));
+ return isSignatureCorrect;
} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
- LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
+ LOGGER.log(Level.SEVERE, e.getLocalizedMessage());
+ return false;
}
}
+
+ public static void main(String[] args) {
+ demonstrateSignature("Text that should be signed to prevent unknown tampering with its content.");
+
+ }
}
diff --git a/src/main/java/com/cryptoexamples/java/ExampleStringEncryptionKeyBasedInOneMethod.java b/src/main/java/com/cryptoexamples/java/ExampleStringEncryptionKeyBased.java
similarity index 62%
rename from src/main/java/com/cryptoexamples/java/ExampleStringEncryptionKeyBasedInOneMethod.java
rename to src/main/java/com/cryptoexamples/java/ExampleStringEncryptionKeyBased.java
index 5c8cfc9..749c9a8 100644
--- a/src/main/java/com/cryptoexamples/java/ExampleStringEncryptionKeyBasedInOneMethod.java
+++ b/src/main/java/com/cryptoexamples/java/ExampleStringEncryptionKeyBased.java
@@ -7,6 +7,7 @@
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
+import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
@@ -17,23 +18,26 @@
import java.util.logging.Logger;
/**
- * All in one example for encryption and decryption of a string in one method;
- * Including
+ * Example for encryption and decryption of a string in one method.
* - Random key generation using strong secure random number generator
* - AES-256 authenticated encryption using GCM
- * - BASE64-encoding as representation for the byte-arrays
+ * - BASE64 encoding as representation for the byte-arrays
+ * - UTF-8 encoding of Strings
* - Exception handling
*/
-public class ExampleStringEncryptionKeyBasedInOneMethod {
- private static final Logger LOGGER = Logger.getLogger(ExampleStringEncryptionKeyBasedInOneMethod.class.getName());
+public class ExampleStringEncryptionKeyBased {
+ private static final Logger LOGGER = Logger.getLogger(ExampleStringEncryptionKeyBased.class.getName());
- public static void main(String[] args) {
- String plainText = "Text that is going to be sent over an insecure channel and must be encrypted at all costs!";
+ /**
+ * Demonstrational method that encrypts the plainText using a newly generated key.
+ * @param plainText
+ * @return true if encryption and decryption were successful, false otherwise
+ */
+ public static boolean demonstrateKeyBasedSymmetricEncryption(String plainText) {
try {
// GENERATE key
- // TODO key should only be generated once and then stored in a secure location.
+ // TODO key should only be generated once and then managed with a key manager/key store.
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
- // 256 bit requires unlimited strength policy files http://www.oracle.com/technetwork/java/javase/downloads
keyGen.init(256);
SecretKey key = keyGen.generateKey();
@@ -47,22 +51,24 @@ public static void main(String[] args) {
GCMParameterSpec spec = new GCMParameterSpec(16 * 8, nonce);
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
- //byte[] aad = "Additional authenticated not encrypted data".getBytes();
- //cipher.updateAAD(aad);
-
- byte[] byteCipher = cipher.doFinal(plainText.getBytes());
+ byte[] byteCipher = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
// CONVERSION of raw bytes to BASE64 representation
- String cipherText = new String(Base64.getEncoder().encode(byteCipher));
+ String cipherText = Base64.getEncoder().encodeToString(byteCipher);
// DECRYPTION
cipher.init(Cipher.DECRYPT_MODE, key, spec);
- //cipher.updateAAD(aad);
byte[] decryptedCipher = cipher.doFinal(Base64.getDecoder().decode(cipherText));
- String decryptedCipherText = new String(decryptedCipher);
+ String decryptedCipherText = new String(decryptedCipher, StandardCharsets.UTF_8);
LOGGER.log(Level.INFO, () -> String.format("Decrypted and original plain text are the same: %b", decryptedCipherText.compareTo(plainText) == 0));
+ return decryptedCipherText.compareTo(plainText) == 0;
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidParameterException | InvalidAlgorithmParameterException e) {
- LOGGER.log(Level.SEVERE, e.getMessage(), e);
+ LOGGER.log(Level.SEVERE, e.getLocalizedMessage());
+ return false;
}
}
+
+ public static void main(String[] args) {
+ demonstrateKeyBasedSymmetricEncryption("Text that is going to be sent over an insecure channel and must be encrypted at all costs!");
+ }
}
diff --git a/src/main/java/com/cryptoexamples/java/ExampleStringEncryptionPasswordBasedInOneMethod.java b/src/main/java/com/cryptoexamples/java/ExampleStringEncryptionPasswordBased.java
similarity index 52%
rename from src/main/java/com/cryptoexamples/java/ExampleStringEncryptionPasswordBasedInOneMethod.java
rename to src/main/java/com/cryptoexamples/java/ExampleStringEncryptionPasswordBased.java
index 7455b6b..666aff9 100644
--- a/src/main/java/com/cryptoexamples/java/ExampleStringEncryptionPasswordBasedInOneMethod.java
+++ b/src/main/java/com/cryptoexamples/java/ExampleStringEncryptionPasswordBased.java
@@ -10,6 +10,7 @@
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
@@ -22,39 +23,43 @@
import java.util.logging.Logger;
/**
- * All in one example for encryption and decryption of a string in one method;
- * Including
+ * Example for encryption and decryption of a string in one method.
* - Random password generation using strong secure random number generator
* - Random salt generation
- * - Key derivation using PBKDF2 HMAC SHA-256,
+ * - Key derivation using PBKDF2 HMAC SHA-512,
* - AES-256 authenticated encryption using GCM
- * - BASE64-encoding as representation for the byte-arrays
+ * - BASE64 encoding as representation for the byte-arrays
+ * - UTF-8 encoding of Strings
* - Exception handling
*/
-public class ExampleStringEncryptionPasswordBasedInOneMethod {
- private static final Logger LOGGER = Logger.getLogger(ExampleStringEncryptionPasswordBasedInOneMethod.class.getName());
+public class ExampleStringEncryptionPasswordBased {
+ private static final Logger LOGGER = Logger.getLogger(ExampleStringEncryptionPasswordBased.class.getName());
- public static void main(String[] args) {
- String plainText = "Text that is going to be sent over an insecure channel and must be encrypted at all costs!";
+ /**
+ * Demonstrational method that encrypts the plainText using a password (that is used to derive the required key).
+ * @param plainText
+ * @param password
+ * @return true if encryption and decryption were successful, false otherwise
+ */
+ public static boolean demonstratePasswordBasedSymmetricEncryption(String plainText, String password) {
try {
// GENERATE password (not needed if you have a password already)
- KeyGenerator keyGen = KeyGenerator.getInstance("AES");
- // Needs unlimited strength policy files http://www.oracle.com/technetwork/java/javase/downloads
- keyGen.init(256);
- String password = Base64.getEncoder().encodeToString(keyGen.generateKey().getEncoded());
+ if(password == null || password.isEmpty()) {
+ KeyGenerator keyGen = KeyGenerator.getInstance("AES");
+ keyGen.init(256);
+ password = Base64.getEncoder().encodeToString(keyGen.generateKey().getEncoded());
+ }
// GENERATE random salt (needed for PBKDF2)
- final byte[] salt = new byte[12];
+ final byte[] salt = new byte[64];
SecureRandom random = SecureRandom.getInstanceStrong();
random.nextBytes(salt);
// DERIVE key (from password and salt)
- SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
- // Needs unlimited strength policy files http://www.oracle.com/technetwork/java/javase/downloads
- KeySpec keyspec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256);
- SecretKey tmp = factory.generateSecret(keyspec);
- SecretKey key = new SecretKeySpec(tmp.getEncoded(), "AES");
-
+ SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
+ KeySpec passwordBasedEncryptionKeySpec = new PBEKeySpec(password.toCharArray(), salt, 10000, 256);
+ SecretKey secretKeyFromPBKDF2 = secretKeyFactory.generateSecret(passwordBasedEncryptionKeySpec);
+ SecretKey key = new SecretKeySpec(secretKeyFromPBKDF2.getEncoded(), "AES");
// GENERATE random nonce (number used once)
final byte[] nonce = new byte[32];
@@ -65,23 +70,25 @@ public static void main(String[] args) {
GCMParameterSpec spec = new GCMParameterSpec(16 * 8, nonce);
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
- //byte[] aad = "Additional authenticated not encrypted data".getBytes();
- //cipher.updateAAD(aad);
-
- byte[] byteCipher = cipher.doFinal(plainText.getBytes());
+ byte[] cipherTextBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
// CONVERSION of raw bytes to BASE64 representation
- String cipherText = new String(Base64.getEncoder().encode(byteCipher));
+ String cipherText = Base64.getEncoder().encodeToString(cipherTextBytes);
// DECRYPTION
cipher.init(Cipher.DECRYPT_MODE, key, spec);
- //cipher.updateAAD(aad);
- byte[] decryptedCipher = cipher.doFinal(Base64.getDecoder().decode(cipherText));
- String decryptedCipherText = new String(decryptedCipher);
+ byte[] decryptedCipherTextBytes = cipher.doFinal(Base64.getDecoder().decode(cipherText));
+ String decryptedCipherText = new String(decryptedCipherTextBytes, StandardCharsets.UTF_8);
LOGGER.log(Level.INFO, () -> String.format("Decrypted and original plain text are the same: %b", decryptedCipherText.compareTo(plainText) == 0));
+ return decryptedCipherText.compareTo(plainText) == 0;
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidParameterException | InvalidAlgorithmParameterException | InvalidKeySpecException e) {
- LOGGER.log(Level.SEVERE, e.getMessage(), e);
+ LOGGER.log(Level.SEVERE, e.getLocalizedMessage());
+ return false;
}
}
+ public static void main(String[] args) {
+ demonstratePasswordBasedSymmetricEncryption("Text that is going to be sent over an insecure channel and must be encrypted at all costs!",null);
+ }
+
}
diff --git a/src/test/java/com/cryptoexamples/java/EncryptedFileTest.java b/src/test/java/com/cryptoexamples/java/EncryptedFileTest.java
deleted file mode 100644
index 0173762..0000000
--- a/src/test/java/com/cryptoexamples/java/EncryptedFileTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.cryptoexamples.java;
-
-import org.junit.Test;
-
-import java.security.GeneralSecurityException;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-
-/**
- * Created by Kai on 12.04.2017.
- */
-public class EncryptedFileTest {
-
-
- public void setUp() {
-
- }
-
-
- public void tearDown() {
-
- }
-
- @Test
- public void testEncryptAndDecryptWithUmlaut() {
- try {
- String password = EncryptedString.generatePassword(32);
- String testString = "Die heiße Zypernsonne quälte Max und Victoria ja böse auf dem Weg bis zur Küste";
- String path = "encryptedFile.enc";
- EncryptedFile encryptedFile = new EncryptedFile();
- encryptedFile.encrypt(testString,password,path);
-
- assertEquals(testString, new EncryptedFile().decrypt(password, path));
- } catch (GeneralSecurityException e) {
- assertTrue(false);
- }
- }
-
- @Test
- public void testEncryptAndDecryptWithASCII() {
- try {
- String password = EncryptedString.generatePassword(32);
- String testString = "A quick movement of the enemy will jeopardize six gunboats.";
- String path = "encryptedFile.enc";
- EncryptedFile encryptedFile = new EncryptedFile();
- encryptedFile.encrypt(testString,password,path);
-
- assertEquals(testString, new EncryptedFile().decrypt(password, path));
- } catch (GeneralSecurityException e) {
- assertTrue(false);
- }
- }
-}
diff --git a/src/test/java/com/cryptoexamples/java/EncryptedStringTest.java b/src/test/java/com/cryptoexamples/java/EncryptedStringTest.java
deleted file mode 100644
index 96aed10..0000000
--- a/src/test/java/com/cryptoexamples/java/EncryptedStringTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.cryptoexamples.java;
-
-import com.cryptoexamples.java.EncryptedString;
-import org.junit.Test;
-
-import java.security.GeneralSecurityException;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-
-/**
- * Created by Kai on 12.04.2017.
- */
-public class EncryptedStringTest {
-
-
- public void setUp() {
-
- }
-
-
- public void tearDown() {
-
- }
-
- @Test
- public void testEncryptAndDecryptWithUmlaut() {
- try {
- String password = EncryptedString.generatePassword(32);
- String testString = "Die heiße Zypernsonne quälte Max und Victoria ja böse auf dem Weg bis zur Küste";
- EncryptedString encryptedString = new EncryptedString().encrypt(testString, password);
- assertEquals(testString, encryptedString.decrypt(password));
- } catch (GeneralSecurityException e) {
- assertTrue(false);
- }
- }
-
- @Test
- public void testEncryptAndDecryptWithASCII() {
- try {
- String password = EncryptedString.generatePassword(32);
- String testString = "A quick movement of the enemy will jeopardize six gunboats.";
- EncryptedString encryptedString = new EncryptedString().encrypt(testString, password);
- assertEquals(testString, encryptedString.decrypt(password));
- } catch (GeneralSecurityException e) {
- assertTrue(false);
- }
- }
-}
diff --git a/src/test/java/com/cryptoexamples/java/EncryptionInOneMethodTests.java b/src/test/java/com/cryptoexamples/java/EncryptionInOneMethodTests.java
index ffc715e..a023870 100644
--- a/src/test/java/com/cryptoexamples/java/EncryptionInOneMethodTests.java
+++ b/src/test/java/com/cryptoexamples/java/EncryptionInOneMethodTests.java
@@ -3,10 +3,12 @@
import org.junit.*;
import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.io.PrintStream;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
/**
@@ -35,33 +37,54 @@ public void resetOut() {
}
@Test
- public void testStringEncryptionPasswordBasedMain() {
- ExampleStringEncryptionPasswordBasedInOneMethod.main(new String[1]);
+ public void testStringEncryptionPasswordBased() throws IOException {
+ ExampleStringEncryptionPasswordBased.main(new String[1]);
+ assertThat(errContent.toString(), containsString("Decrypted and original plain text are the same: true"));
+ errContent.flush();
+ assertTrue(ExampleStringEncryptionPasswordBased.demonstratePasswordBasedSymmetricEncryption("plaintext",null));
assertThat(errContent.toString(), containsString("Decrypted and original plain text are the same: true"));
}
@Test
- public void testStringEncryptionKeyBasedMain() {
- ExampleStringEncryptionKeyBasedInOneMethod.main(new String[1]);
+ public void testStringEncryptionKeyBased() throws IOException {
+ ExampleStringEncryptionKeyBased.main(new String[1]);
+ assertThat(errContent.toString(), containsString("Decrypted and original plain text are the same: true"));
+ errContent.flush();
+ assertTrue(ExampleStringEncryptionKeyBased.demonstrateKeyBasedSymmetricEncryption("plaintext"));
assertThat(errContent.toString(), containsString("Decrypted and original plain text are the same: true"));
}
@Test
- public void testFileEncryptionMain() {
- ExampleFileEncryptionInOneMethod.main(new String[1]);
+ public void testAsymmetricStringEncryption() {
+ ExampleAsymmetricStringEncryption.main(new String[1]);
+ assertThat(errContent.toString(), containsString("Decrypted and original plain text are the same: true"));
+ }
+
+ @Test
+ public void testFileEncryption() throws IOException {
+ ExampleFileEncryption.main(new String[1]);
+ assertThat(errContent.toString(), containsString("Decrypted file content and original plain text are the same: true"));
+ errContent.flush();
+ assertTrue(ExampleFileEncryption.demonstrateFileEncryption("file.enc", "plaintext", null));
assertThat(errContent.toString(), containsString("Decrypted file content and original plain text are the same: true"));
}
@Test
- public void testHashMain() {
- ExampleHashInOneMethod.main(new String[1]);
+ public void testHash() throws IOException {
+ ExampleHash.main(new String[1]);
// uses string: "Text that should be authenticated by comparing the hash of it!"
assertThat(errContent.toString(), containsString("jg0X629+SmdP0/LTHZV/3zXBrizM3/hptRZVIuTXSCtyaqAe0NB8KMld2qebBIXFS1yowCUpCPu93l/fPmKEXg=="));
+ errContent.flush();
+ assertTrue(ExampleHash.demonstrateHash("plaintext"));
+ assertThat(errContent.toString(), containsString("jg0X629+SmdP0/LTHZV/3zXBrizM3/hptRZVIuTXSCtyaqAe0NB8KMld2qebBIXFS1yowCUpCPu93l/fPmKEXg=="));
}
@Test
- public void testSignatureMain() {
- ExampleSignatureInOneMethod.main(new String[1]);
+ public void testSignature() throws IOException {
+ ExampleSignature.main(new String[1]);
+ assertThat(errContent.toString(), containsString("Signature is correct: true"));
+ errContent.flush();
+ assertTrue(ExampleSignature.demonstrateSignature("plainText"));
assertThat(errContent.toString(), containsString("Signature is correct: true"));
}