Can't decrypt openpgpjs (JS) encrypted pgp message with gnupg (Ubuntu GPG via PHP)

时间:2015-11-12 12:01:26

标签: javascript php encryption gnupg openpgp

I'm currently developing a pgp secured web-chat where the encryption is done on client side (Javascript using openpgpjs library) and is stored encrypted in a mysql DB.

In order to send the data to multiple user the server has to decrypt the stored message with PHP code (using gnupg PHP library which uses gpg on Ubuntu server) and re-encrypt it with the public keys of the users before he sends the document to them so that they can decrypt it with javascript.

The problem here: I can use openpgpjs to decrypt openpgpjs encrypted messages and I can use gnupg to decrypt gnupg encrypted messages. BUT I can not use openpgpjs to decrypt gnupg encrypted messages and other way round I can not use gnupg to decrypt openpgpjs encrypted messages.

After testing some scenarios I've compared the outputs of the encrypted text "Hallo!" which has been generated with the same public key but using the different libraries.

So the two outputs are:

"Hallo!" encrypted with openpgpjs library:

-----BEGIN PGP MESSAGE-----
Version: OpenPGP.js v1.3.0
Comment: http://openpgpjs.org

wcFMA2jCJsaw5XYZAQ//XAy31wZyCGTMBv5VIxj6MMeNNGPGXPg72hskWWL8
XQ1r5EAFtqzXU3l7qPvF00d41IKv0L/JHXhz8pBK6ydPtkhiLiX6pEQPUqcx
ifBD68WPvYK/xb9LiGdvPOYN6YqPvqlUky4BcF1fG7b4IlSJGRKgTwnMiHOr
uVu1EOcNLQk6iSwQ1dE18DsJJb/B5zkNrDOjGnloz6LeOXmS3q4 j xA5t2N
DNhr008qXwAw3DsyZ2 QbVHnl8gKBcl2jFmsF5Y/NC4U3jGgnd35uk59AfaW
qPN GKgupP58P6DgzchFUrErrCAEI5S2RC JCAgZm5FJdTWKNwXThODNbLmq
NnBmDja vb/Xlb2l6eKwWdPjulW6QUxi/36aFz16cYso6qtRL6KDLlx/6blb
mKyB2N0mcWQTG V lOh4v2TYjXuZxdJnTmVgwFdpOYSQ5HJNH8olR52OvIPr
m0 DXDuLXtLvsa9SL4CaW9HJ6lkBnQoMBfi8jQb5LqyZOwH53kSuq3imnXdD
QbjVIeJs7RnMDBMc8KPgTYKGZ9incjXGQLphKAylTdXsPKJwyXjJq8xiUygK
asMu0mXKAESm9iW5F5UniN1PifXYi2oD4Y8VCPLsdM3tE/8lZkNa28zPxVEP
8QrwFtVpnRKkg7OyeOq80YzUZVNougujpjANxqhJiqDSPgElygmj/aVUeKyw
kSm0X/C6lAQD3wozzxCZ466fc6/KDrpcTlhQasqWgWydHHcfRG1FILbPflek
g5CZZrwI
=TJcV
-----END PGP MESSAGE-----

"Hallo!" encrypted with gnupg library:

-----BEGIN PGP MESSAGE-----
Version: GnuPG v2.0.22 (GNU/Linux)

hQIMA2jCJsaw5XYZAQ//az5Kc+kbX499ZwPUpDH+owUBkW92TLkN0DQ7sxKUHbGL
B/t7aC8T1G9xqvqrKKFAi3Eidp7RaLHMt/UIr45ZatGRHv6gpBS5LIhzzLx0cyFj
BSzftaV4wyZDM2PBx70rXp9xmYYqsw7bXvtMw7Jp6xrCyOFjVLeCv4sBSmV4rln3
aQepCihyJxWwelmBCGrF8SEClNFkeDC1wo0vfQ8XimFrMuecZWQ3hZ5ORhwvl1Hb
vJQIJ0Uoq8FrN85gpJVZpBsVleLJDBjLTSGVAH++Yirdh+Fv7sxpGolxL3EdjPUg
RfXy8LcTV6PqkgxogPmbCJJ9PEUdDOZHjRbseRArYk32pa7ETiZRDzYL2Oyud5St
1N7SH87PdpFcmZNRI1jM920ZIQv+nOMhwrV60yu2Higc+LXJon+dS9GhsA5roFj5
PXkGWzApGMS9CbJc3vXSEkczWITI1PL5hhjTNXttkeUmvZPIRVK9NPKLMmE5l/N+
GIjKImJZm8YoZBTYOPl06ftxAXnrcnSDzBLdhCe7E0TRVb/dr4PCdv/UBpXA4Boh
LbjyOsc9PkfM51xJPAXX7qfOggT1frnRTFGVcyqrrQrHtYXrTFOQHGJq0a3vVovF
T5fcjzrHkUFVMfAYkvC9xTuMkMKusmhBV1z5unxvHJ5udUZI8V2wlXfJA8S+vITS
QQEmpx+9oO2qi3MAALCtmoB2txjrHKSjxFZp3y/nZbFCtFJrZLXh+hC03SkUmp0z
/NCJQZ971OUwQ6oRR6j5+Nd+
=hFES
-----END PGP MESSAGE-----

as you can see they are clearly different.

So my question is: Is there a difference in the pgp algorithms/versions they are using? On openpgpjs.org it says that openpgpjs is using openpgp.. but this should be compatible to gnupgp, shouldn't it? AND: Is there a way (and what should I do for that?) to use openpgpjs and gnupg together in a compatible way so that I can encrypt and decrypt messages through another?

Thanks in advance!

1 个答案:

答案 0 :(得分:1)

所以我想通了,问题不在库内,它们与另一个兼容,它是通过AJAX POST请求传输加密的PGP消息。

问题是,由于URL语法(POST和GET通过URL语法发送数据),AJAX POST或GET请求正在替换pgp消息的某些字符(例如" +") ,甚至在AJAX Javascript中。)

解决方案:在发送AJG请求之前对BASE64中的pgp消息进行编码,然后在解密之前对其进行解码。

示例:

openpgpjs的Javascript代码(加密消息async并通过AJAX将其发送到服务器以便在PHP中进行数据处理)。

<script src="./lib/js/openpgp.min.js"></script>

<script>
function doEncrypt(inMessage, inRemotePublicKey)
{
    var key = inRemotePublicKey;
    var publicKey = openpgp.key.readArmored(key);

    openpgp.encryptMessage(publicKey.keys, inMessage).then(function(pgpMessage) {
        message = pgpMessage;
    }).catch(function(error) { 
        alert(error);
    }); 
}
</script>

<script>
var message = "";
doEncrypt(message, server_publicKey);
var check = function(){
    if(message != ""){
        message = btoa(message);
        xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() 
        {
            if (xmlhttp.readyState == && xmlhttp.status == 200) 
            {
                alert(xmlhttp.responseText);
            }
        }
        xmlhttp4.open("POST","http://someserver.com/ajax.decryptPGP.php", true);
        xmlhttp4.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xmlhttp4.send("message=" + message);
    }
    else {
        setTimeout(check, 100);
    }
}
check();
</script>

gnupg的PHP代码(在PHP中解密消息并在PHP中执行任何操作)。

<?php
    $res = gnupg_init();
    gnupg_adddecryptkey($res,"<key_fingerprint>","");

    $message = base64_decode($_POST["message"]);
    $message= gnupg_decrypt($res, $message);

    echo 'DECRYPTED JS<pre>' . $message. '</pre><hr />';
?>