Compatibility between OpenPGP and ObjectivePGP

66 Views Asked by At

Building an encrypted system which uses openPGP for keys generation, encryption, decryption for browsers and ObjectivePGP for ios app for the same functions. The issue I am facing is when I generate keys using objectivePGP on my ios app and try to encrypt / decrypt something on browser, it fails. Is there any work around or any better approach that I can follow.

Here is the functions I am using

import * as openpgp from 'openpgp'

export const generateKeyPair = async (): Promise<{
  privateKeyArmored: string
  publicKeyArmored: string
}> => {
  const keys = await openpgp.generateKey({
    type: 'rsa',
    rsaBits: 2048,
    userIDs: [{ name: '', email: '' }],
  })
  return {
    privateKeyArmored: keys.privateKey,
    publicKeyArmored: keys.publicKey,
  }
}

export const pgpEncrypt = async ({
  plainText,
  keys,
}: {
  plainText: string
  keys: Array<string>
}): Promise<string> => {
  const pgpKeys: openpgp.Key[] = []

  for (let i = 0; i < keys.length; i++) {
    pgpKeys.push(await openpgp.readKey({ armoredKey: keys[i] }))
  }
  const message: openpgp.Message<string> = await openpgp.createMessage({
    text: plainText,
  })
  const encrypted: string = <string>await openpgp.encrypt({
    message: message,
    encryptionKeys: pgpKeys,
  })
  return encrypted
}

export const sign = async ({
  message,
  signingKey,
}: {
  message: string
  signingKey: string
}): Promise<string> => {
  const messageObject: openpgp.Message<string> = await openpgp.createMessage({
    text: message,
  })
  const privateKey: openpgp.PrivateKey = await openpgp.readPrivateKey({
    armoredKey: signingKey,
  })
  return <string>await openpgp.sign({
    message: messageObject,
    signingKeys: privateKey,
    detached: true,
  })
}

export const verifySignature = async ({
  messageContent,
  signatureArmored,
  publicKeyArmored,
}: {
  messageContent: string
  signatureArmored: string
  publicKeyArmored: string
}): Promise<void> => {
  const message: openpgp.Message<string> = await openpgp.createMessage({
    text: messageContent,
  })
  const signature: openpgp.Signature = await openpgp.readSignature({
    armoredSignature: signatureArmored,
  })
  const publicKey: openpgp.PublicKey = await openpgp.readKey({
    armoredKey: publicKeyArmored,
  })
  const verificationResult = await openpgp.verify({
    message,
    signature,
    verificationKeys: publicKey,
  })
  const { verified } = verificationResult.signatures[0]
  try {
    await verified
  } catch (e) {
    throw new Error('Signature could not be verified: ' + e)
  }
}

export const pgpDecrypt = async ({
  cipherText,
  toPrivateKeyArmored,
}: {
  cipherText: any
  toPrivateKeyArmored: string
}): Promise<string> => {
  const message = await openpgp.readMessage({ armoredMessage: cipherText })
  const privateKey: openpgp.PrivateKey = await openpgp.readPrivateKey({
    armoredKey: toPrivateKeyArmored,
  })

  const { data: decrypted } = await openpgp.decrypt({
    message,
    decryptionKeys: privateKey,
  })

  return decrypted as string
}

Working Script

import {
  pgpEncrypt,
  pgpDecrypt,
  generateKeyPair,
} from './pgp'

const main = async () => {
  // Generate
  const { privateKeyArmored, publicKeyArmored } = await generateKeyPair()
  console.log(privateKeyArmored)
  console.log(publicKeyArmored)

  // Encrypt
  const text = 'I am a secret'
  const encryptedText = await pgpEncrypt({
    plainText: text,
    keys: [publicKeyArmored],
  })
  console.log(encryptedText)

  // Decrypt
  const decryptedText = await pgpDecrypt({
    cipherText: encryptedText,
    toPrivateKeyArmored: privateKeyArmored,
  })
  console.log(decryptedText)
}
main()

Non Working Script ( Keys generated using ObjectivePGP )

import {
  pgpEncrypt,
  pgpDecrypt,
} from './pgp'

const main = async () => {
  // Generate
  const privateKeyArmored = `-----BEGIN PGP PRIVATE KEY BLOCK-----
  Version: ObjectivePGP
  Comment: https://objectivepgp.com
  Charset: UTF-8
  
  xcLYBGSv/dwBCADEjAZ4+CyWp//PqBtf13RCL0ch6PvhfRrhc8hMIMDEDcEsBK8cnPmBYar/OuRz
  dAH27L+CM6yFiwzKJk2oqSZJcrZyiJFL091/rr5CuvyqrWwJ7kKb/MCRM2sOE+NWYNzjV/QH6uPB
  1FLXfKGJXd0vC5mp4DyP+dtEhijpjrB172QmT4wPHVwXIkE3MOhk2qePaMzDlLKw80VcVFHu0cUp
  rwCaxYTFd8tn4uNtIjDSrIPbhtG0wG/pziawGGbhp34QGq74zzASlXOFD235Pi1UbliyiGiMHUoj
  LMDQSZSFJyPb3Fn8VkDwv3QBk9LPqBgk/YNCoDl2MAAmRMiejCGNABEBAAEAB/9isFiTpzFkWGjH
  UQalwh5bGTgjW8QVveaga62YJB4Gk016l8OBn4RcpbjhvSV2nzpZTRj//IhU6bP7UO5PkNdrq9DW
  g6JJK9GdShW4lgFGhhuohN0nS+s5PVM012GgPrTK5p/e1d+UtNL/5lGKEvp7o9x9gt2GAZRKvP6P
  /5i1LiNGa8QRl96ALgjmvKDKjRlKXr8+pg+KpMJnV7I76ad9F7a0oeRdJm9GjTXaOm3JerEsd3/V
  oE67nl7FfXFQDgcUMzFngnIAAObdNobeD5C9336iwYFAIkte/ecW7TfRYh5NQi0SbT5wIG3uGvTj
  UJHM9CrrorCTA/NWbws7sHx1BAD6IBaohPbsfCDEOtSDOnsvV1mBSyFiATFV2v+JJoQ1tX0M7Esi
  Vy11NvpKj/7ujtd3A5W3KwHNPQJAWL0LS32qbOhr0n+96euJFh/R+i2bSAbGZ2Kl+tPkp+1DffHM
  qDF1TLBI28jxWV3K820Ba54aPTk+ZMWrRnQ77euZ3Kc1TwQAySnKLse5sYFYSJG9HxIiA0Yd9FJM
  ItofU/4BMmZkHCnmOlEUnPSm1OVXr2vDz+I6FdHgWCKaW1plLRzIiWtllnkpXZot64vyTBimhzJ5
  4BbH1L58OqeaEtxlcfEK0/Ckb2r8aDjEYg6WeZag1uWEeKtn4XI2OjeCRfK0DL9cPGMD/3dHDKzj
  rLZ+M7d5P/al5aHwkbwlKFM9yIphRUCSqz4sApR8cMohM7Al155448fVLeJgx97docmH78FctK46
  FLz3jqU4U1kdjWPPKMbJ2qcYg1hPzxQGVPa5lW5SXkcdeTyowsBlQJXZsLRk7NfPq7Of82KedZNv
  wzVI7yETk/bkQ8jNAMLAkQQTAQIAJAUCZK/93AIbAwQVCAkKBwsJCAcDAgEEFgIBAwIeAQIXgAIZ
  AQAhCRA4HtKHFpXy+xYhBFIIELsU7sTLS6f+Rjge0ocWlfL7rLQH/1bncejoHw0wC63L8/r0U9rm
  A2cAXGOX3k0oDVaMrlVnfsODqhBmmRMmSJYTWSD+D6/lKdvM822dY1+w3jVVFr2QcYZKa5od9auf
  92uWgh9aHAHke5/GVPey2if/1vZtJjwzS+BHkS6SxbrW1HK2blxezHGqy7QeSQAmmipreTj8Zvbz
  yywhBSno7ul2gW9y+wA0/DyJ8BXi3cPXodX81otdNERpUqwqyn7VlvokJGsqfRLxP4ViNsc2kZMV
  REK1TxbFjp/42i95UAARj93SKz
  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
  =6OZt
  -----END PGP PRIVATE KEY BLOCK-----`

  const publicKeyArmored = `-----BEGIN PGP PUBLIC KEY BLOCK-----
  Version: ObjectivePGP
  Comment: https://objectivepgp.com
  Charset: UTF-8
  
  xsBNBGSv/dwBCADEjAZ4+CyWp//PqBtf13RCL0ch6PvhfRrhc8hMIMDEDcEsBK8cnPmBYar/OuRz
  dAH27L+CM6yFiwzKJk2oqSZJcrZyiJFL091/rr5CuvyqrWwJ7kKb/MCRM2sOE+NWYNzjV/QH6uPB
  1FLXfKGJXd0vC5mp4DyP+dtEhijpjrB172QmT4wPHVwXIkE3MOhk2qePaMzDlLKw80VcVFHu0cUp
  rwCaxYTFd8tn4uNtIjDSrIPbhtG0wG/pziawGGbhp34QGq74zzASlXOFD235Pi1UbliyiGiMHUoj
  LMDQSZSFJyPb3Fn8VkDwv3QBk9LPqBgk/YNCoDl2MAAmRMiejCGNABEBAAHNAMLAkQQTAQIAJAUC
  ZK/93AIbAwQVCAkKBwsJCAcDAgEEFgIBAwIeAQIXgAIZAQAhCRA4HtKHFpXy+xYhBFIIELsU7sTL
  S6f+Rjge0ocWlfL7rLQH/1bncejoHw0wC63L8/r0U9rmA2cAXGOX3k0oDVaMrlVnfsODqhBmmRMm
  SJYTWSD+D6/lKdvM822dY1+w3jVVFr2QcYZKa5od9auf92uWgh9aHAHke5/GVPey2if/1vZtJjwz
  S+BHkS6SxbrW1HK2blxezHGqy7QeSQAmmipreTj8ZvbzyywhBSno7ul2gW9y+wA0/DyJ8BXi3cPX
  odX81otdNERpUqwqyn7VlvokJGsqfRLxP4ViNsc2kZMVREK1TxbFjp/42i95UAARj93SKzqfKzxu
  EOaZQeXQ1uLbZSGmYjBaZLV25gVxNx55D/r02g01Uf0NgM8dvtcpaa0CGljOwM0EZK/93AEMAOEG
  qL2a6ODpyZyeX8wMpBIEfchpSxAl3zw0sK22VOwoXc3T83RjC75fh5uZGoliXi7mAnYrcapJlLKL
  1CpGdowHRWIbY0OW+4wvVDsGPGbRAteRTsMXUgsAanAKu8r0zqLRY/JrpSlLn9Sr1PS8RLoMX+n0
  6ZECJiWPnic+nM/jiwI23kWfrZPhKY6C7nG8OnHmOLij2a+sBzmaeeVFmbD/T+HqI3UqYFTInBuZ
  D+HACTGTMo/bsoIs/MyHy+EreH7VHeAB9Cm7K0h4r8M4/dwWEZqVriuYF5APWvMgjnQmagmV02Az
  Z+Jgm9dINJBLKovs8AOtnvdT27vBU7jraLJ+aswQnjWI7wFfogawAN24Le31RMpuMPb9P8QhNUuK
  V8d8QMj2ox/Z40ivWoEmvwSraE2iV04zrYtVhY3MMLBS+95eAHNA2wxPBnQPwY8l3WKSFWQbPhfa
  f5mGAh2JW2C6sBSfEB4FlQMEv1vtPFqwSFDoc7uZPe8nq1orAMT8EwARAQABwsGVBBgBAgEoBQJk
  r/3dAhsMwF0gBBkBAgAGBQJkr/3dAAoJEDge0ocWlfL7mvcH/iArl8O4bEvyXTWDvAGiBYExHrco
  TpFGePWxjxwLhBVqBfZtk8DPp8kKMo1SOBBL9BYhU82JklhlzRfBubGt91c5/BoRSzjiekuZVu5L
  qoq64C2udPGTfdPxNHP50oQLOx1I7M9U1bZQxJLlBD0nIkOAi6diQ9fpl8LVJ8U2xuDIQm3ssYqJ
  NF57geZfGYgF8bu96NhSeJ2CsK0DLiWvBherrzp5ihxdkPHfj2NscCW67LowzVTjyakDTOwjhc6o
  kPTseYh2rJQM5l2bcpRTaXHshPzCGptjD618LM1wCtjmb5ZaGDUAZAo4nqoqZVbVS1c5tV+D5m0q
  iVB6FTXm8v8AIQkQOB7ShxaV8vsWIQRSCBC7FO7Ey0un/kY4HtKHFpXy+8buB/9fjaBV3cgeOfuP
  Aojp4mPD39A4+BAMNr5X8vCRLFCszwqm3thxS9PQtGL6LKbCWJ/M3dMu+fVMslxF3rEKjB9EkS5N
  lH83xOlnqpwxHXq6SbxNDNVo1w4WvfR5O3C8yPIzE+qOQV0jd6eIFm2KcdNTOY1eCx7wYhgz6GOk
  xw5Q/8f+LYuf2V4ecSbk/8eNHXvnItnqOHa0Z0dUtgBSb77zR3dPRKiMGmYYr5OA+gWaYqAgDlPs
  kcxnhWcx+TB25mNQYjNG07b92OqEfwSVyk2kXeamLjtVXVgRV7iL4D6IthUsIXew5XGA4dQgnvSr
  Hwf2pKQXW0xREurMz+WOtcGc
  =WC1q
  -----END PGP PUBLIC KEY BLOCK-----`

  // Encrypt
  const text = 'I am a secret'
  const encryptedText = await pgpEncrypt({
    plainText: text,
    keys: [publicKeyArmored],
  })
  console.log(encryptedText)

  // Decrypt
  const decryptedText = await pgpDecrypt({
    cipherText: encryptedText,
    toPrivateKeyArmored: privateKeyArmored,
  })
  console.log(decryptedText)
}
main()

0

There are 0 best solutions below