User:Higgs1/lastlog

Java
Cipher.getInstance is expensive, so here it is only called once and the result is stored as a static final.

To load user data from a file: load(File file);

To save user data to a file: save(new UserData(String username, String password);

To get the default lastlogin file, use: new File(getMinecraftWorkingDir, "lastlogin");

import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec;

public class LastlogCodec { public static class UserData { public String username; public String password; public UserData(final String username, final String password) { this.username = username; this.password = password; }	}	private static final Key            key       = new SecretKeySpec(	                                                   new byte[] {	    (byte) 0xd8, (byte) 0x08, (byte) 0x77, (byte) 0xe7, (byte) 0x61,	    (byte) 0xac, (byte) 0xd9, (byte) 0x1d         }, "DES"); private static final IvParameterSpec paramspec = new IvParameterSpec(	                                                  new byte[] {	    (byte) 0xc0, (byte) 0x05, (byte) 0x86, (byte) 0x92, (byte) 0xec,	    (byte) 0x67, (byte) 0xcf, (byte) 0x39         }); private static final Cipher         cipher    = getCipher; private static final Cipher getCipher { try { return Cipher.getInstance("DES/CBC/PKCS5Padding"); } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {} return null; }	private static synchronized boolean initCipher(final int mode) { try { cipher.init(mode, key, paramspec); return true; } catch (InvalidKeyException | InvalidAlgorithmParameterException		   | NullPointerException e) {} return false; }	public static synchronized UserData load(final InputStream is) throws IOException { @SuppressWarnings("resource") final DataInputStream dis = new DataInputStream(		   initCipher(Cipher.DECRYPT_MODE)		        ? new CipherInputStream(is, cipher)		        : is); final UserData data = new UserData(dis.readUTF, dis.readUTF); dis.close; return data; }	public static synchronized void save(final OutputStream os,	   final UserData data) throws IOException { final DataOutputStream dos = new DataOutputStream(		   initCipher(Cipher.ENCRYPT_MODE)		        ? new CipherOutputStream(os, cipher)		        : os); dos.writeUTF(data.username); dos.writeUTF(data.password); dos.close; } }