crypto.ts 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import { Injectable } from "@angular/core";
  2. import { TwitterApiProvider } from "../twitter-api/twitter-api";
  3. import { P2pStorageIpfsProvider } from "../p2p-storage-ipfs/p2p-storage-ipfs";
  4. import { Storage } from "@ionic/storage";
  5. @Injectable()
  6. export class CryptoProvider {
  7. ownUserId: string;
  8. constructor(
  9. private twitter: TwitterApiProvider,
  10. private ipfs: P2pStorageIpfsProvider,
  11. private storage: Storage
  12. ) {
  13. this.init();
  14. }
  15. private async init() {
  16. this.ownUserId = await this.storage.get("userId");
  17. }
  18. public async publishPublicKey(key: string) {
  19. let publicKeyHistory;
  20. // Get user description
  21. const userData = await this.twitter.fetchUser(this.ownUserId);
  22. const profileDescription = userData["description"];
  23. // Extract link to public key
  24. const link = this.extractLinkFromDescription(profileDescription);
  25. // Fetch public key history
  26. if (link.length) {
  27. publicKeyHistory = await this.ipfs.fetchJson(link);
  28. }
  29. // Todo: avoid publishing the same public key twice - check if new key equals newest key in history
  30. // Add new key to history
  31. const newKey = {
  32. key: key,
  33. validFrom: Date.now()
  34. };
  35. if (link.length) {
  36. publicKeyHistory["keys"].push(newKey);
  37. } else {
  38. publicKeyHistory = {
  39. keys: [newKey]
  40. };
  41. }
  42. // Publish updated key history...
  43. const res = await this.ipfs.storePublicKey(publicKeyHistory);
  44. // ... and update description in user profile
  45. this.twitter.updateProfileDescription(
  46. "ipfs://" + res["Hash"] + " #hybridOSN"
  47. );
  48. }
  49. private extractLinkFromDescription(profileDescription: string): string {
  50. for (let word of profileDescription.split(" ")) {
  51. if (this.isLink(word)) {
  52. return word.substr(7);
  53. }
  54. }
  55. return "";
  56. }
  57. private isLink(word: string): boolean {
  58. const hits = word.match(/ipfs:\/\/Qm[a-zA-Z0-9]+/);
  59. return hits != null;
  60. }
  61. public async generateRsaKeys() {
  62. return await crypto.subtle.generateKey(
  63. {
  64. name: "RSA-OAEP",
  65. modulusLength: 1024,
  66. publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
  67. hash: { name: "SHA-256" }
  68. },
  69. true,
  70. ["encrypt", "decrypt"]
  71. );
  72. }
  73. public async extractPrivateKey(keys): Promise<string> {
  74. return btoa(
  75. String.fromCharCode.apply(
  76. null,
  77. new Uint8Array(await crypto.subtle.exportKey("pkcs8", keys.privateKey))
  78. )
  79. );
  80. }
  81. public async extractPublicKey(keys): Promise<string> {
  82. return btoa(
  83. String.fromCharCode.apply(
  84. null,
  85. new Uint8Array(await crypto.subtle.exportKey("spki", keys.publicKey))
  86. )
  87. );
  88. }
  89. }