What is a digital certificate?

First read the question What is a digital signature? You’ll then understand what the problem is with those signatures. You can’t really proof that the public key that the sender owns to decrypt the message actually belongs to you. That’s where a digital certificate comes in. Those certificates are issued by a certificate authority (CA) which you would have to pay and give lots of information about your identity. You’d also have to send them your public key. The CA uses all this information to generate a certificate and send it back to you. The standard for digital certificates is X.509. It contains information about your identity, your public key and things like a validity period, etc. It’s important that you choose a well-known CA that other people will trust. The CA will have encrypted the certificate with their private key.

When party A now sends a message to party B, it will sign the message with his certificate. Party B will ensure this certificate is correct by decrypting it using the CA’s public key. Now party B has access to your public key and can decrypt the signature to verify the authentication.

BTW, you can also generate a certificate yourself (eg. using the tool keytool) and use that. But people are not likely to accept that certificate as there is no trusted third party involved.

The standard for digital certificates is X.509. This standard allows for certificate chaining. This allows certificates to be put in a hierarchy. Maybe party B doesn’t trust the first CA, but goes up in the hierarchy and finds one that he trusts. For example, an employee of a company might get a certificate from his company who is in turned signed by Thawte (the root CA). Now suppose that employee uses his certificate to try to get the receiver trust him. The receiver isn’t eager to trust the one that issued the certificate, but since that certificate is signed in turn by Thawte, he trust the original certificate.

Generating a MAC that uses MD5 in Java

The following example generates a random key of 128 bits (16 bytes) necessary for HmacMD5 and computes a hash using this key. The key would have to be shared between sender and receiver.

Main.java:

import javax.crypto.spec.*;
import javax.crypto.Mac;
import java.security.*;
import javax.crypto.*;
import sun.misc.*;
 
public class Main
{
   public static void main(String []args) throws Exception {
      String message = "the sun is green and the grass shines";
 
      byte[] b = generateMAC(message);
      System.out.println("HMAC-MD5 for message '" + message + "':");
      System.out.println("t" + new BASE64Encoder().encode(generateMAC(message)));
   }
 
   public static byte[] generateMAC(String message) throws Exception {
      // generate key
      SecureRandom sr = new SecureRandom();
      byte[] b = new byte[20];
      sr.nextBytes(b);
      SecretKey key = new SecretKeySpec(b, "HmacMD5");
 
      // generate message digest based on key
      Mac mac = Mac.getInstance("HmacMD5");
      mac.init(key);
 
      return mac.doFinal(message.getBytes());
   }
}

outputs:

HMAC-MD5 for message 'the sun is green and the grass shines':
        JX25ruAB1qM0w39rTQnPGA==

What is asymmetric cryptography?

The problem with symmetric cryptography is how to distribute the secret key to the involved parties. In assymetric cryptography (also: public key cryptography), algorithms use two different keys: a private and a public one. A message encrypted with a private key can be decrypted with its public key (and in some cases vice versa). The owner of the key pair holds the private key, and may distribute the public key to anyone. Someone who wants to send a secret message uses the public key of the intended receiver to encrypt it. Only the receiver holds the private key and can decrypt it.

Compared to secret key encryption, public key encryption is slow.

A popular assymetric cryptographic algorithm is RSA, used in PGP.

Aligning decimal numbers to the decimal fields

You can use the class FieldPosition and one of the Format classes. FieldPosition keeps track of where a certain part in the formatted string is located. Those parts are dependent on the type of Format class you use and are defined in constants. For example, the class DateFormat contains constants like DAY_OF_WEEK_FIELD or MONTH_FIELD. Likewise, the NumberFormat class contains two constants: INTEGER_FIELD and FRACTION_FIELD. When you invoke the method format, you can supply an instance of FieldPosition which will be filled in with information about the position of the field (beginIndex and endIndex).

Main.java:

import java.text.*;
 
public class Main {
   public static void main(String args[]) {
      double array[] = { 0, 0.1, 1.0, 213.034, 12.43, 12, 0.9832, 4567 };
 
      NumberFormat nf = NumberFormat.getInstance();
      StringBuffer buffer = new StringBuffer();
      for (int i=0; i<array.length; i++) {
         FieldPosition fp = new FieldPosition(NumberFormat.FRACTION_FIELD);
         buffer.setLength(0);
         nf.format(array[i], buffer, fp);
 
         alignInColumn(buffer, fp);
      }
   }
 
   public static void alignInColumn(StringBuffer sb, FieldPosition fp) {
      int col = 10-fp.getBeginIndex();
      if (fp.getBeginIndex() == fp.getEndIndex())
         col--;
 
      for (int i=0; i<col; i++) { 
         System.out.print(' ');
      }
      System.out.println(sb);
   }
}

outputs:

        0
        0.1
        1
      213.034
       12.43
       12
        0.983
    4,567

Fetching today’s date in Java

Try this:

import java.util.*;
import java.text.*;
 
public class Main { 
   public static void main(String[] args) throws Exception {
      System.out.println(getDateTime("dd-MM-yyyy HH:mm:ss.SSS"));
   }
 
   public static String getDateTime(String format) {
      Calendar calendar = Calendar.getInstance();
      SimpleDateFormat dateFormat = new SimpleDateFormat(format);
      Date date = calendar.getTime();
      return dateFormat.format(calendar.getTime());
   }
}

Using java.util.logging to log to an XML file

Use the standard XMLFormatter class, already used by default by several standard handlers.

Main.java:

import java.util.logging.*;
import java.io.*;
 
public class Main
{
   public static void main(String argv[]) {
      Logger logger = Logger.getLogger("main");
      logger.setUseParentHandlers(false);
      ConsoleHandler ch = new ConsoleHandler();
      ch.setLevel(Level.ALL);
      logger.addHandler(ch);
 
      ch.setFormatter(new XMLFormatter());

      LogRecord logRecord = new LogRecord(Level.SEVERE, "Something went seriously wrong");
      logRecord.setMillis(1000);
      logRecord.setParameters(new Object[] { "param1", "param2" });
      logRecord.setSequenceNumber(123456);
      logRecord.setSourceClassName(Main.class.getName());
      logRecord.setSourceMethodName("main");

      logger.log(logRecord); 
   }
}

outputs:

<? xml version="1.0" encoding="windows-1252" standalone="no"?>
<!DOCTYPE log SYSTEM "logger.dtd">
<log>
<record>
  <date>1969-12-31T16:00:01</date>
  <millis>1000</millis>
  <sequence>123456</sequence>
  <level>SEVERE</level>
  <class>Main</class>
  <method>main</method>
  <thread>10</thread>
  <message>Something went seriously wrong</message>
</record>

A Grep utility that makes uses of Java’s RegEx package

Here’s a simple example that gets you started. It allows you to search a pattern (-cpat) in a set of files that match a certain regular expression (-fpat). You can specify a directory from where it should start searching with the option -root. -R tells the grepper to recurse through subdirectories. Below are a couple examples.

Grep.java:

import java.util.regex.*;
import java.io.*;
 
public class Grep
{
   Pattern pattern;
   FileFilter fileFilter;
 
   public Grep(String contentRegex) {
      pattern = Pattern.compile(contentRegex);
   }
 
   public void searchInDir(String startDir, String dirRegex, boolean recurse) 
                                                 throws IOException {
      final Pattern patternFile = Pattern.compile(dirRegex);
      fileFilter = new FileFilter() {
         public boolean accept(File f) {
            if (f.isDirectory()) return true;
 
            Matcher m = patternFile.matcher(f.getName());
            if (m.matches()) return true;
            return false;
         }
      };
 
      searchInDir_aux(new File(startDir), recurse);
   }
    
   public void searchInDir_aux(File dir, boolean recurse) throws IOException {
      File[] contents = dir.listFiles(fileFilter);
      for (int i=0; i<contents.length; i++) {
         File fileToCheck = contents[i];
         if (fileToCheck.isFile()) {
            searchInFile(fileToCheck);
         }
         else if (recurse) {
            searchInDir_aux(fileToCheck, recurse);
         }
      }            
   } 
 
   public void searchInFile(File file) throws IOException {
      System.out.println("=====> " + file);
      BufferedReader br = new BufferedReader(new FileReader(file));
      String line = null;
      int count=0;
      while ((line = br.readLine()) != null) {
         count++;
         Matcher m = pattern.matcher(line);
         while (m.find()) {
            System.out.println(count + ": " + line);
            System.out.print(count + ": ");
            indent(m.start());
            System.out.print("^");
            indent(m.end()-m.start()-2);
            System.out.println("^");
         }
      } 
      br.close();
   }
 
   public static void indent(int h) {
      for (int i=0; i<h; i++) 
         System.out.print(' ');
   }
 
   public static void main(String []args) throws Exception {
      String contentPattern=null, filePattern=null, startDir=null;
      boolean recurse = false;
  
      int i = -1;
      while (++i < args.length) {
         String arg = args[i];
	 if (!arg.startsWith("-")) {
            System.err.println("argument error: " + arg + "n");
            printUsage();
            System.exit(1);
         }  
         if (arg.equals("-fpat")) {
            if (i == args.length-1 || args[i+1].startsWith("-")) {
               System.err.println("Missing filename RE pattern");
               printUsage();
               System.exit(1);
            }
            filePattern = args[++i];
            continue;
         }
         else if (arg.equals("-cpat")) {
            if (i == args.length-1 || args[i+1].startsWith("-")) {
               System.err.println("Missing contents RE pattern");
               printUsage();
               System.exit(1);
            }
            contentPattern = args[++i];
            continue;
         }
         else if (arg.equals("-R")) {
            recurse = true;
            continue;
         }
         else if (arg.equals("-root")) {
            if (i == args.length-1 || args[i+1].startsWith("-")) {
               System.err.println("Missing starting directory");
               printUsage();
               System.exit(1);
            }
            startDir = args[++i];
            continue;
         }
      }                  
      if (contentPattern == null || filePattern == null) {
         printUsage();
         System.exit(1);
      }
      if (startDir == null) {
         startDir = ".";          // take current directory
      }
 
      Grep grep = new Grep(contentPattern);
      grep.searchInDir(startDir, filePattern, recurse);
   }
 
   private static void printUsage() {
      System.err.println("Usage: java [optional] -fpat fileRegex -cpat contentRegex");
      System.err.println("Where [optional] is one of the following:");
      System.err.println("    -R  recursively search subdirectories");
      System.err.println("    -root <STARTDIR>  specifies starting directory");
      System.exit(1);
   }
}

For example:

(searches all files for the pattern import)
  
C:myregextest> c:jdk1.4binjava Grep -fpat .* -cpat import
=====> .Grep$1.class
=====> .Grep.class
=====> .Grep.java
1: import java.util.regex.*;
1: ^    ^
2: import java.io.*;
2: ^    ^
 
(recursively searches c:winnt for files ending on .ini for the pattern micro.{5})
 
C:myregextest> c:jdk1.4binjava Grep -R -root c:winnt -fpat .*.ini -cpat micro.{5}
 
. . . [result]  

Zipping a file in Java

The following example creates a zip file of the file that you provide at command line.

Main.java:

import java.util.zip.*;
import java.io.*;
 
public class Main
{
   public static void main(String []args) throws Exception {
      if (args.length != 1) {
         System.err.println("Usage: java Main <file>");
         System.exit(1);
      }
 
      FileOutputStream fos = new FileOutputStream(args[0] + ".zip");
      BufferedOutputStream bos = new BufferedOutputStream(fos);
      ZipOutputStream zos = new ZipOutputStream(bos);
 
      File inFile = new File(args[0]);
      FileInputStream fis = new FileInputStream(inFile);
      BufferedInputStream bis = new BufferedInputStream(fis);
      
      ZipEntry zipEntry = new ZipEntry(inFile.toString());
      zipEntry.setMethod(ZipEntry.DEFLATED);
      zos.putNextEntry(zipEntry);
 
      byte[] buffer = new byte[1024];
      int length;
      while ((length = bis.read(buffer)) != -1) {
         zos.write(buffer, 0, length);
      }
  
      zos.closeEntry();
      zos.close();
      bis.close();
   }
}