Showing posts with label rsa. Show all posts
Showing posts with label rsa. Show all posts

Sunday, 12 October 2014

Private Key for Digital Signature, KeyStore, PKCS#12

The following demonstrates the use of the Java security API to digitally sign a document.
Before we get to the Scala code, we must first use Java's keytool to create a self-signed certificate.
In real-life, you'd probably buy one from Verisign for example. The archive file format chosen is PKCS12.
keytool -genkey
        -alias tj
        -keystore mykeystore
        -storepass storepass
        -validity 365
        -keyalg RSA
        -keysize 2048
        -storetype pkcs12
Once you have answered the questions, you can list the aliases using the following command:
keytool -keystore mykeystore 
        -storepass storepass 
        -list 
        -storetype pkcs12
Should output:
Keystore type: PKCS12
Keystore provider: SunJSSE

Your keystore contains 1 entry

tj, Oct 12, 2014, PrivateKeyEntry,
Certificate fingerprint (SHA1): 52:6B:0D:05:9E:CE:5A:CA:5E:EF:74:C9:51:FE:46:8D:E6:CE:4F:11
Let's get to the coding part. We will extract the private key from the store to digitally sign a document. I usually first create a digest from the initial document and store this digest as base 64. But there is no need for this step.
  def createDigest(legalDocument: String): Array[Byte] = {
    val md = MessageDigest.getInstance("SHA-256")
    md.update(legalDocument.getBytes)
    md.digest()
  }
to be called like this:
val alias = "tj"
val password = "storepass".toCharArray
val legalDoc = createDigest("This is a legal document I must digitally sign")
legalDoc is an array of bytes - it contains a SHA-256 digest from the initial document.

The code to list the keystore entries, just to make sure we are on the right path:
  def listStoreEntries(password: Array[Char]): KeyStore = {
    val keyStoreDefaultType = KeyStore.getDefaultType
    val keyStore = KeyStore.getInstance("pkcs12")
    keyStore.load(new FileInputStream("mykeystore"), password)

    val aliases = keyStore.aliases()
    while(aliases.hasMoreElements) {
      val alias = aliases.nextElement()
      log(s" Alias: $alias")
    }

    keyStore
  }
listStoreEntries returns the initialized keystore. Let's now sign the legal document and return a base 64 encoded digital signature:
  def signLegalDocument(keystore: KeyStore, alias: String, password: Array[Char], legalDoc: Array[Byte]): String = {
    val privateKey = keystore.getKey(alias, password)
    val dsig = Signature.getInstance("MD5withRSA")
    dsig.initSign(privateKey.asInstanceOf[PrivateKey])
    dsig.update(legalDoc)
    val signature = dsig.sign()
    Base64.getEncoder.encodeToString(signature)
  }
And the code to verify the signature:
  def verifyDigitalSignature(keystore: KeyStore, alias: String, legalDoc: Array[Byte], signature: String): Unit = {
    val certificate = keystore.getCertificate(alias)
    val x509Certificate = certificate.asInstanceOf[X509Certificate]
    val publicKey = x509Certificate.getPublicKey
    val dsig = Signature.getInstance("MD5withRSA")
    dsig.initVerify(publicKey)

    val sig = Base64.getDecoder.decode(signature)
    dsig.update(legalDoc)
    val verifiedSig = dsig.verify(sig)
    log(s"Has the legal document signature successfully been verified? $verifiedSig")
    require(verifiedSig == true)
  }
The whole main method:
  def main(args: Array[String]) {
    val alias = "tj"
    val password = "storepass".toCharArray
    val legalDoc = createDigest("This is a legal document I must digitally sign")
    val keyStore = listStoreEntries(password)

    val signature = signLegalDocument(keyStore, alias, password, legalDoc)
    verifyDigitalSignature(keyStore, alias, legalDoc, signature)
  }

  def log(ref: Any) = println(ref)
How do I import my self-signed certificate into Windows cert manager?
Just rename the keystore from mykeystore to mykeystore.pfx On Windows, simple double-click on it and follow the instructions.
Open certmgr.msc via the run command or from a DOS console - under Certificates - Currrent User, Personal, Certificates you should see your previously create certificate using Java's keytool.

Friday, 13 February 2009

RSA explicit with encryption

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);

KeyPair keyPair = keyGen.generateKeyPair();

RSAPublicKey pubKey = (RSAPublicKey)keyPair.getPublic();
RSAPrivateKey priKey = (RSAPrivateKey)keyPair.getPrivate();

System.out.println("PUB KEY: " + pubKey.getPublicExponent() + ", " + pubKey.getModulus());
System.out.println("PRI KEY: " + priKey.getPrivateExponent());

Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);

String plainMsg = "Hello world!";

byte[] cryptedData = cipher.doFinal(plainMsg.getBytes());

cipher.init(Cipher.DECRYPT_MODE, priKey);

String clearMsg = new String(cipher.doFinal(cryptedData));

System.out.println(clearMsg);

Sunday, 18 January 2009

RSA in C# and Java

Following up on the previous post, follows an implementation of RSA in C# and Java.

First the Java version that generates a public key:


KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(4096);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
RSAPublicKey rsaPublicKey = (RSAPublicKey)publicKey;
BigInteger publicExponent =rsaPublicKey.getPublicExponent();
BigInteger modulus = rsaPublicKey.getModulus();



with the public exponent and the modulus, you can export this key in an xml file or stream that will be used by the C# client to read the public key.

The C# part:


var rsaCryptoServiceProvider = new RSACryptoServiceProvider();
const string keyfileName = "PKI2.xml";
var streamReader = new StreamReader(@"C:\TEMP\RSAJavaPubKey.xml");

string publicKey = streamReader.ReadToEnd();
rsaCryptoServiceProvider.FromXmlString(publicKey);
streamReader.Close();



Now what?

Let's say you are using Rendez-Vous as a protocol and you are looking for a way to cipher messages between the client and the server. the Java server can generate a public key on start-up, initiate a handshake with the C# (or Java client). The client generates a symmetric key for DES-3 or AES, the client then encrypts the symmetric key with the server's public key, sends it to the server which deciphers the symmetric key, and then you have your SSL-like protocol on top of RV.

This obviously does not solve the man in the middle attack.

Blog Archive