Skip to content

Instantly share code, notes, and snippets.

@RyuzakiKK
Last active May 24, 2017 15:52
Show Gist options
  • Save RyuzakiKK/f589b46e2f3280d57c97aceefa18232a to your computer and use it in GitHub Desktop.
Save RyuzakiKK/f589b46e2f3280d57c97aceefa18232a to your computer and use it in GitHub Desktop.
Supposed to print NoteCrypt Database. Mostly copy/paste from "notecrypt/utils"
package com.notecrypt.utils;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
/**
* https://github.com/RyuzakiKK/NoteCrypt/tree/master/app/src/main/java/com/notecrypt/utils
*
* @author Ludovico de Nittis
*/
interface INotes {
/**
* Returns the title of the note.
*
* @return
*/
String getTitle();
/**
* Returns the text of the note.
*
* @return
*/
String getNote();
/**
* Returns the tags of the note.
*
* @return
*/
String getTags();
/**
* Returns if the note is starred.
*
* @return
*/
boolean isStarred();
/**
* Sets the title of the note.
*
* @param title
*/
void setTitle(String title);
/**
* Sets the text of the note.
*
* @param note
*/
void setNote(String note);
/**
* Sets the tags of the note.
*
* @param tags
*/
void setTags(String tags);
/**
* Sets the starred value of the note.
*
* @param starred
*/
void setStarred(boolean starred);
}
class Notes implements java.io.Serializable, INotes {
private static final long serialVersionUID = 1212L;
private String title;
private String note;
private String tags;
private boolean starred;
/**
* Creates a new note with the parameters provided in input.
*
* @param title title for the note
* @param note text of the note
*/
Notes(final String title, final String note) {
super();
this.title = title;
this.note = note;
}
@Override
public String getTitle() {
return title;
}
@Override
public String getNote() {
return note;
}
@Override
public String getTags() {
return tags;
}
@Override
public boolean isStarred() {
return starred;
}
@Override
public void setTitle(final String title) {
this.title = title;
}
@Override
public void setNote(final String note) {
this.note = note;
}
@Override
public void setTags(final String tags) {
this.tags = tags;
}
@Override
public void setStarred(boolean starred) {
this.starred = starred;
}
}
interface IDatabaseForNotes {
/**
* First string to display in the tag filter 'listTag'.
*/
String ALL_ITEMS = "ALL";
/**
* The key in the 'list' for the title.
*/
String TITLE = "Title";
/**
* The key in the 'list' for the position.
*/
String POSITION = "Position";
/**
* Keyword Tags.
*/
String TAGS = "Tags";
/**
* Keyword Note.
*/
String NOTE = "Note";
String STAR = "Star";
/**
* Returns the notes.
*
* @return Map of notes
*/
Map<Long, Notes> getNotes();
/**
* Returns the map with tags and the id of the notes that use them.
*
* @return map of tags
*/
Map<String, TreeSet<Long>> getMapTag();
/**
* Returns the 'list' of notes.
*
* @return List of id and title for the listview
*/
List<Map<String, String>> getList();
/**
* Returns the 'listTag' of used tags.
*
* @return List of tags used for the listview
*/
List<String> getListTag();
/**
* Returns the current position.
*
* @return the free position where add a new note
*/
long getPosition();
/**
* Sets the notes.
*
* @param notes new notes that need to be set
*/
void setNotes(Map<Long, Notes> notes);
/**
* Need to be called the first time the database is created or when is loaded from a file.
*/
void initializeLists();
/**
* Add a note or edit an existing one at the position 'id'.
*
* @param title title of the note
* @param note text of the note
* @param tags new tags of the note
* @param oldTags old tags before the edit
* @param id position of the add or edit
*/
void addNote(String title, String note, String tags, String oldTags, Long id, boolean star);
/**
* Delete the note at the position 'id'.
*
* @param id position of the note
* @param oldTags tags existing in the current note
*/
void deleteNote(Long id, String oldTags);
/**
* Find all notes with the specific tag.
*
* @param tag string to search
* @return Map with all notes that have the specific tag
*/
Map<Long, Notes> findTag(String tag);
}
class DatabaseForNotes implements java.io.Serializable, IDatabaseForNotes {
private static final int INITIAL_NOTES = 64;
private static final int INITIAL_TAG = 32;
private static final long serialVersionUID = 12321L;
private transient List<Map<String, String>> list;
private transient List<String> listTag; //DEPRECATED, need to be deleted?
private long position; // 0 by default
private Map<Long, Notes> notes = new HashMap<>(INITIAL_NOTES);
private final Map<String, TreeSet<Long>> mapTag = new HashMap<>(INITIAL_TAG);
/* (non-Javadoc)
* @see com.notecrypt.utils.IDatabaseForNotes#getNotes()
*/
@Override
public Map<Long, Notes> getNotes() {
return this.notes;
}
/* (non-Javadoc)
* @see com.notecrypt.utils.IDatabaseForNotes#getMapTag()
*/
@Override
public Map<String, TreeSet<Long>> getMapTag() {
return this.mapTag;
}
/* (non-Javadoc)
* @see com.notecrypt.utils.IDatabaseForNotes#getList()
*/
@Override
public List<Map<String, String>> getList() {
return this.list;
}
/* (non-Javadoc)
* @see com.notecrypt.utils.IDatabaseForNotes#getListTag()
*/
@Override
public List<String> getListTag() { //DEPRECATED, need to be removed?
return this.listTag;
}
/* (non-Javadoc)
* @see com.notecrypt.utils.IDatabaseForNotes#getPosition()
*/
@Override
public long getPosition() {
return this.position;
}
/* (non-Javadoc)
* @see com.notecrypt.utils.IDatabaseForNotes#setNotes(java.util.Map)
*/
@Override
public void setNotes(final Map<Long, Notes> notes) {
this.notes = notes;
}
/* (non-Javadoc)
* @see com.notecrypt.utils.IDatabaseForNotes#initializeLists()
*/
@Override
public void initializeLists() {
if (list == null) {
list = new ArrayList<>();
}
if (listTag == null) {
listTag = new LinkedList<>();
}
}
/* (non-Javadoc)
* @see com.notecrypt.utils.IDatabaseForNotes#addNote(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.Long)
*/
@Override
public void addNote(final String title, final String note, final String tags, final String oldTags, final Long id, final boolean star) {
notes.put(id, new Notes(title, note));
notes.get(id).setStarred(star);
String localOldTags = oldTags;
notes.get(id).setTags(tags);
// If there are some change
if (!tags.equals(localOldTags)) {
if (localOldTags == null) { //avoid nullPointer exception
localOldTags = "";
}
String[] tagsArray = tags.split(",");
String[] oldTagsArray = localOldTags.split(",");
for (int i = 0; i < tagsArray.length; i++) {
tagsArray[i] = tagsArray[i].trim().toLowerCase(Locale.ENGLISH);
}
for (int i = 0; i < oldTagsArray.length; i++) {
oldTagsArray[i] = oldTagsArray[i].trim().toLowerCase(Locale.ENGLISH);
}
//Create a Set for avoid problems with duplicated tags (if there are 2 or more equals tags on the same note)
final Set<String> tagsSet = new HashSet<>(Arrays.asList(tagsArray));
final Set<String> oldTagsSet = new HashSet<>(Arrays.asList(oldTagsArray));
// Delete all removed tags
for (final String tag : oldTagsSet) {
if (!localOldTags.equals("") && !tagsSet.contains(tag)) {
removeTag(id, tag);
}
}
// Add all new tags
for (final String string : tagsSet) {
//if this is a new tag and isn't empty
if (!oldTagsSet.contains(string) && !string.equals("")) {
TreeSet<Long> tempSet = mapTag.get(string);
if (tempSet == null) {
tempSet = new TreeSet<>();
}
tempSet.add(id);
mapTag.put(string, tempSet);
}
}
}
if (id == position) { //if this is a new add and not an edit of an existing note
position++;
}
}
/* (non-Javadoc)
* @see com.notecrypt.utils.IDatabaseForNotes#deleteNote(java.lang.Long, java.lang.String)
*/
@Override
public void deleteNote(final Long id, final String oldTags) {
notes.remove(id);
if (oldTags != null) {
final String[] oldTagsArray = oldTags.split(",");
for (int i = 0; i < oldTagsArray.length; i++) {
oldTagsArray[i] = oldTagsArray[i].trim().toLowerCase(Locale.ENGLISH);
}
final Set<String> oldTagsSet = new HashSet<>(Arrays.asList(oldTagsArray));
for (final String tag : oldTagsSet) {
if (!tag.equals("")) {
removeTag(id, tag);
}
}
}
}
/* (non-Javadoc)
* @see com.notecrypt.utils.IDatabaseForNotes#findTag(java.lang.String)
*/
@Override
public Map<Long, Notes> findTag(final String tag) {
final TreeSet<Long> tempSet = mapTag.get(tag);
final HashMap<Long, Notes> tempNotes = new HashMap<>(notes);
tempNotes.keySet().retainAll(tempSet);
return tempNotes;
}
/**
* Check if the note is visible with the current filter.
*
* @param filter current filter on the view
* @param tags tags used on the current note
* @return true if the note is visible on the current view
*/
static boolean isNoteVisible(final String filter, final String tags) {
final String[] tagsArray = tags.split(",");
for (int i = 0; i < tagsArray.length; i++) {
tagsArray[i] = tagsArray[i].trim().toLowerCase(Locale.ENGLISH);
}
for (final String string : tagsArray) {
if (filter.equals(string)) {
return true;
}
}
return false;
}
/**
* Insert the position and title information.
*
* @param position position of the element to insert
* @param title title of the element
* @return Map with the provided information
*/
static Map<String, String> putData(final String position, final String title, final boolean star) {
final HashMap<String, String> item = new HashMap<>();
item.put(POSITION, position);
item.put(TITLE, title);
item.put(STAR, String.valueOf(star));
return item;
}
/**
* Remove a tag from 'mapTag'.
*
* @param id id of the tag
* @param tag String of the tag
*/
private void removeTag(final Long id, final String tag) {
final TreeSet<Long> tempSet = mapTag.get(tag);
tempSet.remove(id);
if (tempSet.isEmpty()) {
mapTag.remove(tag);
} else {
mapTag.put(tag, tempSet);
}
}
}
class Cryptox {
private static final int IV_SIZE = 16;
//for encrypt with AES 128 bit
private static final int KEY_SIZE = 128;
private static Cryptox singleton = new Cryptox();
private Cryptox() {
}
/**
* Returns the singleton.
*
* @return singleton of Crypto
*/
public static Cryptox getInstance() {
return singleton;
}
/**
* Generate a random initialization vector.
*
* @return random generated IV
*/
byte[] generateIv() {
final SecureRandom random = new SecureRandom();
final byte[] ivBytes = new byte[IV_SIZE];
random.nextBytes(ivBytes);
return ivBytes;
}
byte[] deriveKey(String password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException
{
SecretKeyFactory kf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec specs = new PBEKeySpec(password.toCharArray(), salt, 1024, KEY_SIZE);
SecretKey key = kf.generateSecret(specs);
return key.getEncoded();
}
}
public class PrintNoteCryptDB {
private static DatabaseForNotes CryptoLoad(String path, String key){
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream(path));
byte[] salt2 = (byte[]) ois.readObject();
byte[] byteKey = Cryptox.getInstance().deriveKey(key, salt2);
SecretKeySpec secretKey = new SecretKeySpec(byteKey, "AES");
//Creation of Cipher objects
Cipher decrypt = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] iv = (byte[]) ois.readObject();
IvParameterSpec ivspec = new IvParameterSpec(iv);
decrypt.init(Cipher.DECRYPT_MODE, secretKey, ivspec);
byte[] original = decrypt.doFinal((byte[]) ois.readObject());
ByteArrayInputStream bais = new ByteArrayInputStream(original);
ObjectInputStream dis = new ObjectInputStream(bais);
final DatabaseForNotes db = (DatabaseForNotes) dis.readObject();
if (db == null) {
throw new InvalidKeyException();
}
return db;
} catch (Exception e) {
System.out.println("NoteCrypt: " + String.valueOf(e));
return null;
} finally {
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
System.out.println("NoteCrypt: " + "IOException");
}
}
}
}
public static void main(String[] args)
{
if(args.length == 2)
{
DatabaseForNotes dbn = CryptoLoad(args[0], args[1]);
if(dbn == null)
return;
Map<Long, Notes> notes = dbn.getNotes();
//StringBuilder concatedNotes = new StringBuilder("");
String plainNote = "";
for(Notes note : notes.values())
{
plainNote = String.format("===%s===\n%s\n===END===\n\n", note.getTitle(), note.getNote());
//concatedNotes.append(plainNote);
System.out.print(plainNote);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment