Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Server migrate #73

Merged
merged 4 commits into from
Mar 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 44 additions & 29 deletions client/app/services/crypto.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import * as encoding from "text-encoding";
/**
* Data Objects
*/
export interface IKeyPair {
keyType: string;
privateKey: Uint8Array;
publicKey: Uint8Array;
}

export interface IEncryptedData {
readonly hashedRid: string;
Expand Down Expand Up @@ -58,11 +63,11 @@ const sodiumPromise = sodium.ready;

/**
* Key-Pair Generation
* @param {object} ocKeys - Callisto Options Counselor public-private key pair (Uint8Array[32])
* @param {object} userKeys - User public-private key pair (Uint8Array[32]) for message authentication
* @param {IKeyPair} ocKeys - Callisto Options Counselor public-private key pair (Uint8Array[32])
* @param {IKeyPair} userKeys - User public-private key pair (Uint8Array[32]) for message authentication
*/
let ocKeys;
let userKeys;
let ocKeys: IKeyPair;
let userKeys: IKeyPair;

sodiumPromise.then(() => {
ocKeys = sodium.crypto_box_keypair();
Expand Down Expand Up @@ -92,8 +97,9 @@ export class CryptoService {
public encryptData(plainText: IPlainTextData): IEncryptedData {

const encryptedRecord: string = this.symmetricEncrypt(sodium.from_base64(plainText.recordKey),
JSON.stringify(plainText.record));
const encryptedRecordKey: string = this.symmetricEncrypt(sodium.from_base64(plainText.kId), plainText.recordKey);
JSON.stringify(plainText.record));
const encryptedRecordKey: string = this.symmetricEncrypt(sodium.from_base64(plainText.kId),
plainText.recordKey);

// base64 encoding
const cY: string = this.encryptSecretValue(plainText.y);
Expand All @@ -105,7 +111,7 @@ export class CryptoService {
userPubKey: sodium.to_base64(userKeys.publicKey),
cY,
cX: plainText.hashedX.toString(),
kId: plainText.kId, // TODO: change this when we decide what userID
kId: plainText.kId,
};
}

Expand Down Expand Up @@ -140,7 +146,7 @@ export class CryptoService {
* @returns {IDecryptedData}
*/
public decryptData(): IDecryptedData {
const data = this.getMatchedData();
const data: IEncryptedData[] = this.getMatchedData();
if (data.length < 2) {
return { decryptedRecords: [], slope: bigInt(0), rid: "0", coords: [] };
}
Expand Down Expand Up @@ -174,8 +180,15 @@ export class CryptoService {
* @returns {string} randomized perp id
*/
private randomizePerpId(perpId: string): string {
<<<<<<< HEAD

const sK: string = "Project Callisto Super Secret Key";
return sodium.to_base64(sodium.crypto_hash(perpId + sK));

=======
const sK: string = "Project Callisto Super Secret Key";
return sodium.to_base64(sodium.crypto_hash(perpId + sK));
>>>>>>> ba0858b2e9571e699ac8a754a34a985373bb3a18
}

/**
Expand Down Expand Up @@ -213,7 +226,8 @@ export class CryptoService {
const ridLen: number = hexRid.length;
const slope: bigInt.BigInteger = bigInt(hexRid.substr(0, ridLen / 2), this.HEX);

const kId = sodium.crypto_generichash(sodium.crypto_generichash_BYTES, hexRid.substr(ridLen / 2, ridLen));
const kId: Uint8Array = sodium.crypto_generichash(sodium.crypto_generichash_BYTES,
hexRid.substr(ridLen / 2, ridLen));
return { slope, kId };
}

Expand All @@ -224,9 +238,9 @@ export class CryptoService {
*/
private encryptSecretValue(y: bigInt.BigInteger): string {

const nonce = sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES);
const cY = sodium.crypto_box_easy(y.toString(), nonce, ocKeys.publicKey, userKeys.privateKey);
const encrypted = sodium.to_base64(cY) + "$" + sodium.to_base64(nonce);
const nonce: Uint8Array = sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES);
const cY: Uint8Array = sodium.crypto_box_easy(y.toString(), nonce, ocKeys.publicKey, userKeys.privateKey);
const encrypted: string = sodium.to_base64(cY) + "$" + sodium.to_base64(nonce);

return encrypted;
}
Expand All @@ -239,10 +253,10 @@ export class CryptoService {
* @returns {IPlainTextData} all values needed to be encrypted
*/
private generateDataValues(rid: string, userId: string, record: IRecord): IPlainTextData {
const prgRid = sodium.to_hex(sodium.crypto_hash(sodium.from_base64(rid)));
const prgRid: string = sodium.to_hex(sodium.crypto_hash(sodium.from_base64(rid)));

const derived = this.deriveFromRid(prgRid);
const hashedUserId = bigInt(sodium.to_hex(sodium.crypto_hash(userId)), this.HEX);
const derived: IRIDComponents = this.deriveFromRid(prgRid);
const hashedUserId: bigInt.BigInteger = bigInt(sodium.to_hex(sodium.crypto_hash(userId)), this.HEX);
const bigIntRid: bigInt.BigInteger = bigInt(prgRid, this.HEX);

return {
Expand All @@ -252,7 +266,7 @@ export class CryptoService {
kId: sodium.to_base64(derived.kId),
record,
hashedX: hashedUserId,
y: derived.slope.times(hashedUserId).plus(bigIntRid),
y: derived.slope.times(hashedUserId).plus(bigIntRid).mod(bigInt(2 ** 128).minus(159)),
};
}

Expand All @@ -263,9 +277,9 @@ export class CryptoService {
* @returns {string} ciphertext concatenated with a nonce, both in base 64 encoding
*/
private symmetricEncrypt(key: Uint8Array, msg: string): string {
const nonce = sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES);
const cT = sodium.crypto_secretbox_easy(msg, nonce, key);
const encrypted = sodium.to_base64(cT) + "$" + sodium.to_base64(nonce);
const nonce: Uint8Array = sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES);
const cT: Uint8Array = sodium.crypto_secretbox_easy(msg, nonce, key);
const encrypted: string = sodium.to_base64(cT) + "$" + sodium.to_base64(nonce);

return encrypted;
}
Expand All @@ -276,17 +290,18 @@ export class CryptoService {
* @param {string} rid - randomized perpetrator ID
* @returns {Array<IRecord>} array of decrypted records
*/
/* TODO: Figure out type of rid*/
private decryptRecords(data: IEncryptedData[], rid): IRecord[] {
private decryptRecords(data: IEncryptedData[], rid: string): IRecord[] {

const decryptedRecords: IRecord[] = [];
const derived = this.deriveFromRid(rid.toString(this.HEX));
const derived: IRIDComponents = this.deriveFromRid(rid);

for (let i = 0; i < data.length; i++) {
for (const i in data) {
const encryptedRecord: string = data[i].encryptedRecord;
// TODO: resolve type IO
const decryptedRecordKey = this.symmetricDecrypt(data[i].kId, data[i].encryptedRecordKey);
const decryptedRecord = this.symmetricDecrypt(decryptedRecordKey, encryptedRecord);
const decryptedRecordKey: Uint8Array = this.symmetricDecrypt(sodium.from_base64(data[i].kId),
data[i].encryptedRecordKey);

const decryptedRecord: Uint8Array = this.symmetricDecrypt(sodium.from_base64(decryptedRecordKey),
encryptedRecord);
const dStr: string = new encoding.TextDecoder("utf-8").decode(decryptedRecord);
decryptedRecords.push(JSON.parse(dStr));
}
Expand All @@ -295,17 +310,17 @@ export class CryptoService {

/**
* Symmetric decryption
* @param {string} key
* @param {string} key - base 64 encoding
* @param {string} cipherText - base 64 encoding
* @returns {Uint8Array} decrypted value
*/
private symmetricDecrypt(key: string, cipherText: string) {
private symmetricDecrypt(key: Uint8Array, cipherText: string): Uint8Array {
const split: string[] = cipherText.split("$");

// Uint8Arrays
const cT: Uint8Array = sodium.from_base64(split[0]);
const nonce: Uint8Array = sodium.from_base64(split[1]);
const decrypted = sodium.crypto_secretbox_open_easy(cT, nonce, sodium.from_base64(key));
const decrypted: Uint8Array = sodium.crypto_secretbox_open_easy(cT, nonce, key);

return decrypted;
}
Expand Down
Loading