This Java library provides simple-to-use routines for everyday cryptography tasks.
It does target limited environments (such as for use in an app updater) and as such tries to minimize dependencies (currently: JDK8 only).
Currently implemented utilities:
- Read keys/certificates stored in PKCS8 format, PEM encoded, optionally protected with password
- Create digests (checksums) using strong cryptographic algorithms (like SHA256/SHA512)
- Sign files/digests using strong cryptographic algorithms (like SHA256/SHA256 with RSA)
- verify these signatures
<dependency>
<groupId>ch.dvbern.oss.cryptutil</groupId>
<artifactId>cryptutil</artifactId>
<version>${cryptutil.version}</version>
</dependency>Create a cryptographically strong digest/checksum using DigestEngine
bytedigestBytes[] = newDigestEngine().digestSHA256(is, null);
// openssl compatible: hex-encoding, lowercaseStringhexText = DatatypeConverter.printHexBinary(digestBytes).toLowerCase(Locale.US);Or wrapping an InputStream:
MessageDigestmessageDigest = newDigestEngine().configureSHA256(null);
DigestInputStreamwrapped = newDigestInputStream(inputStream, messageDigest);
// ... do your stream processing herebytedigestBytes[] = wrapped..getMessageDigest().digest()
// openssl compatible: hex-encoding, lowercaseStringhexText = DatatypeConverter.printHexBinary(digestBytes).toLowerCase(Locale.US);Read Keys/Certificates stored in a PKCS#8 PEM file using PKCS8PEM
// read public key/certificateRSAPublicKeypublicKey = newPKCS8PEM().readCertFromPKCS8EncodedPEM(privateKeyURL.openStream());
// read password protected private keyRSAPrivateKeyprivateKey = newPKCS8PEM().readKeyFromPKCS8EncodedPEM(privateKeyURL.openStream(), "asdffdsa".toCharArray());Create a cryptographically strong file signature on a digest and verify it using SignatureEngine
// read private keyRSAPrivateKeyprivateKey = ... seeexampleabove// create digestbytedigestBytes[] = ... seeexampleaboveByteArrayInputStreamdigestByteStream = newByteArrayInputStream(digestBytes);
// sign digest@NonNullbyte[] signatureBytes = newSignatureEngine().signSHA256RSA(privateKey, digestByteStream, null);
writeToFile(signatureBytes, "path/to/signed-digest.bin");// verifyRSAPublicKeypublicKey = ... seeeExampleabovebytedigestBytes[] = ... seeDigestEngineexampleaboveInputStreamdigestByteStream = newByteArrayInputStream(digestBytes);
bytesignatureBytes[] = readFromFile("path/to/signed-digest.bin");
@NonNullbooleanverified = newSignatureEngine().verifySHA256RSA(publicKey, digestByteStream, signatureBytes, null);The following information is also used to generate data for use in unit tests.
Generate an keypair using OpenSSL
First, create the RSA private key using 4096 bits (do not omit the password!):
openssl genrsa -out mykey.pem 4096
Java (i.e.: this library) needs the certificate in PKCS#8 format, so convert it:
openssl pkcs8 -topk8 -inform PEM -in mykey.pem -out mykey-pkcs8.pem
Now generate a public key:
openssl rsa -in mykey.pem -pubout > mykey.pub
Generate signed digests and verify them using OpenSSL
Taken from: Stackoverflow: openssl-command-line-to-verify-the-signature
Generated a RSA signed SHA256 digest using our private key:
openssl dgst -sha256 -sign mykey.pem -out foo.txt.sha256.signed foo.txt Verify this digest using our public key:
openssl dgst -sha256 -verify mykey.pub -signature foo.txt.sha256.signed foo.txt
=> Verified OK
See comments in pom.xml for more details.
- Maven - Dependency Management
- Love :)
Please read CONTRIBUTING.md for the process for submitting pull requests to us.
One healthy social atmospehere is very important to us, wherefore we rate our Code of Conduct high. For details check the file CODE_OF_CONDUCT.md
- DV Bern AG, Christoph Linder - Initial work - dvbern
See also the list of contributors who participated in this project.
This project is licensed under the Apache 2.0 License - see the LICENSE.md file for details.
Strings might get (explicitly or accidentally) interned and thus last longer in memory than expected.
This is clearly unwanted behavior.
Since having backwards compatibility would expose unsafe behavior, breaking the cryptutil API (change passwords from String to char[]) is the only way.
When upgrading from 1.x to 2.x of cryptutil, we recommend to migrate your code to use char[] for passwords, too!
If you cannot do this: just use "yourPassword".toCharArray() when passing the password argument.