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
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
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()