【问题标题】:JavaScript: Decrypt content of GnuPG encrypted files using openpgp.jsJavaScript:使用 openpgp.js 解密 GnuPG 加密文件的内容
【发布时间】:2016-02-14 18:16:04
【问题描述】:

我正在尝试使用 openpgp.js 在 JavaScript 中为 GnuPG 加密文件编写示例解密器。

所以我天真地尝试了它,甚至没有问它是否可能。我做了以下页面。

popup.html

<!doctype html>
<!--
-->
<html>
<head>
    <title>Popup</title>
    <script src="openpgp.js"></script>
    <script src="popup.js"></script>
</head>
<body>
    <p>Upload message: </p><input id="message" type="file"/><br>

    <p>Upload secret key: </p><input id="secret" type="file"/><br>

    <p>Secret key password: </p><input id="password" type="password"/><br><br>
    <button id="decrypt">Decrypt</button>
    <p id="output"></p>

    <div id="loadingDiv"></div>
</body>
</html>

popup.js

var message = "";
var secret = "";


function readMessage (e) {
    var file = e.target.files[0];
    if (!file) {
        message = "";
    }
    var reader = new FileReader();
    reader.onload = function (e) {
        message = e.target.result;
    };
    reader.readAsText (file);
}


function readSecret (e) {
    var file = e.target.files[0];
    if (!file) {
        secret = "";
    }
    var reader = new FileReader();
    reader.onload = function (e) {
        secret = e.target.result;
    };
    reader.readAsText (file);
}




function loadScript(url, callback)
{
    var head = document.getElementsByTagName ("head")[0];
    var script = document.createElement ("script");
    script.type = "text/javascript";
    script.src = url;

    script.onreadystatechange = callback;
    script.onload = callback;

    head.appendChild(script);
}


document.addEventListener ("DOMContentLoaded", function() {
    document.getElementById ("message").addEventListener("change", readMessage, false);
    document.getElementById ("secret").addEventListener("change", readSecret, false);
    var gen = function() {
        document.getElementById ("decrypt").addEventListener ("click", function() {
            var output = document.getElementById ("output");
            output.style.color = "black";
            if (document.getElementById ("message").value == "") {
                output.innerHTML = "No message provided";
                output.style.color = "red";
            }
            else if (document.getElementById ("secret").value == "") {
                output.innerHTML = "No secret key provided";
                output.style.color = "red";
            }
            else if (document.getElementById ("password").value == "") {
                output.innerHTML = "No password for secret key provided";
                output.style.color = "red";
            }
            else {
                var privateKey = openpgp.key.readArmored (secret).keys[0];
                var isCorrect = privateKey.decrypt (document.getElementById ("password").value);
                if (isCorrect) {
                    output.innerHTML = "";
                    output.style.color = "black";
                    var img = document.createElement ("img");
                    img.src = "loading.gif";
                    img.id = "loading";
                    document.getElementById ("loadingDiv").appendChild (img);
                    message = openpgp.message.readArmored (message);
                    openpgp.decryptMessage (privateKey, message).then (function (plaintext) {
                        output.innerHTML = plaintext;
                    }).catch (function(error) {
                        output.innerHTML = "Error while decrypting";
                        output.style.color = "red";
                    });
                }
                else {
                    output.innerHTML = "Incorrect password";
                    output.style.color = "red";
                }
            }
        });
    }
    loadScript ("openpgp.js", gen);
});

openpgp.js 在message = openpgp.message.readArmored (message); 上给出Unknown ASCII armor type 错误。

那么有可能吗?如果是,我应该做一些不同的事情吗?

【问题讨论】:

  • 请更具体地说明错误消息出现的确切位置(哪一行)。猜测:您尝试加载使用 ASCII 铠装编码的二进制信息。
  • @JensErat 对不起,当我试图打开一条消息(编辑问题)时,你能详细说明你的猜测吗,我不太明白
  • OpenPGP 标准中有两种“编码”,一种(空间)效率更高的二进制编码和 ASCII 铠装(类似于 base64)。如果您的消息以-----BEGIN PGP MESSAGE----- 之类的开头,则您使用的是ASCII 装甲。我readArmored只会读取ASCII装甲消息。
  • 是的,它是二进制编码的,你是对的。我试图将字节转换为消息(message.fromBinary (bytes)),但消息没有被解密(Parameter "utf8" is not of type string
  • @JensErat 我可以将二进制编码转换为在 js 中装甲的 ascii 吗?

标签: javascript gnupg pgp openpgp.js


【解决方案1】:

OpenPGP 知道消息的编码,

  • 二进制消息,更节省空间和
  • ASCII 铠装消息以类似于 base64 的格式编码,在以纯文本形式通过不同渠道传输时提供更高的可靠性。

openpgp.message.readArmored (message) 只理解 ASCII 装甲信息。请改用openpgp.message.fromBinary (message)。作为替代方案,在加密时使用--armor 选项通过GnuPG 对消息进行编码,或者gpg --enarmor 已加密的二进制消息。

【讨论】:

  • 我改成message = openpgp.message.fromBinary (message),然后消息没有解密(Parameter "utf8" is not of type string)
  • 很抱歉,我对 JavaScript 的了解不够深入,无法理解在处理二进制信息时可能会出现什么问题。我猜你在使用网络技术时限制使用 ASCII 装甲消息会更安全。
  • 即便如此,库确实可以正确解密文本文件,但在图像上却不能正确解密
【解决方案2】:

使用 Openpgpjs 版本 3.x,我发现必须创建一个私钥对象并将其与选项变量中的 publicKey 和消息一起使用。私钥对象是用私钥创建的。首先创建私钥对象,然后用你的“秘密”短语解密它,然后解密消息。

这是一个使用变量的示例。

 privKeyObj.decrypt(secret).then(function(oBoolean) {
      //Name oBoolean anything you want.
      //It will be true or false indicating
      //whether the secret phrase is right.
      if(!oBoolean) {
           output.innerHTML = "Incorrect password.";
           output.style.color = "red";
      } 
      else {
           var privateKey = "your openpgpjs private key created with your secret phrase";
           var privKeyObj = openpgp.key.readArmored(privateKey).keys[0];
           var options = {
                message: openpgp.message.readArmored(message),
                publicKeys: openpgp.key.readArmored(publickey).keys,
                privateKeys: [privKeyObj]
           };
           openpgp.decrypt(options).then(function(plaintext) {
                output.innerHTML = plaintext.data;
           }, function(error) {
                output.innerHTML = "Error while decrypting";
                output.style.color = "red";
           });
      }
 });

【讨论】:

    猜你喜欢
    • 2019-08-10
    • 1970-01-01
    • 2016-02-28
    • 1970-01-01
    • 2012-07-02
    • 2021-02-20
    • 2012-06-19
    • 1970-01-01
    • 2016-06-08
    相关资源
    最近更新 更多