【问题标题】:Error while generating key with GPGME使用 GPGME 生成密钥时出错
【发布时间】:2016-01-25 13:48:50
【问题描述】:

我正在尝试使用 GPGME 生成一个新密钥,但不幸的是我无法使以下代码工作:

 std::string def = "<GnupgKeyParms format='internal'>"
                    " Key-Type: default "
                    " Subkey-Type: default"
                    " Name-Real: Joe Tester"
                    " Name-Comment: with stupid passphrase"
                    " Name-Email: joe2@foo.bar"
                    " Expire-Date: 0"
                    " Passphrase: abc"
                    " </GnupgKeyParms>";

            gpgme_error_t error = gpgme_op_genkey(mContext, def.c_str(), NULL, NULL);

            if(GPG_ERR_INV_VALUE  == error){
                std::cout << "Value error";
            }
            if(GPG_ERR_NOT_SUPPORTED == error){
                std::cout << "Not supported error";
            }
            if(GPG_ERR_GENERAL  ==  error){
                std::cout << "general error";
            }
            if(error == GPG_ERR_NO_ERROR){
                gpgme_genkey_result_t res = gpgme_op_genkey_result(mContext);
                if(res->primary && res->sub){
                    result = true;
                }
            }
        }

条件error == GPG_ERR_NO_ERROR 不成立。事实上,没有任何错误检查条件。我的调试器只是告诉我error 的值是 117440567。初始化看起来像这样:

gpgme_engine_info_t info;
    gpgme_error_t  error;
    const char * CONFIG_DIR = "/";

    // Initializes gpgme
    gpgme_check_version(NULL);

    // Initialize the locale environment.
    setlocale(LC_ALL, "");
    gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL));
#ifdef LC_MESSAGES
    gpgme_set_locale(NULL, LC_MESSAGES, setlocale(LC_MESSAGES, NULL));
#endif
    error = gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP, NULL,
                                  CONFIG_DIR);
    if(error)
        return false;
    error = gpgme_new(&mContext);
    if(error)
        return false;
    // Check OpenPGP
    error = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
    if(error)
        return false;
    // load engine info
    error = gpgme_get_engine_info(&info);
    if(error)
        return false;
    while(info && info->protocol != gpgme_get_protocol(mContext)) {
        info = info->next;
    }     

    if(error)
        return false;    

我在这里没有收到任何错误。我完全能够使用 GnuPG 命令行创建密钥。那么使用 GPGME 创建密钥时出现的这个奇怪错误是什么意思呢?

UDAPTE:

感谢 Auges 的回答,我现在可以判断它是 GPG_ERR_INV_VALUE,这意味着参数字符串格式错误。但为什么?我必须用空格以外的东西来分隔这些值吗?

更新

我改了internal的引号

GnupgKeyParms format=\"internal\"

但现在我收到了GPG_ERR_GENERAL。

更新:

字符串现在看起来像:

std::string def = "<GnupgKeyParms format=\"internal\"> \n"
                    " Key-Type: default \n"
                    " Subkey-Type: default \n"
                    " Name-Real: Joe Tester3 \n"
                    " Name-Comment: with stupid passphrase \n"
                    " Name-Email: joe3@foo.bar \n"
                    " Expire-Date: 0 \n"
                    " Passphrase: abc \n"
                    " </GnupgKeyParms>";

但应用程序在gpgme_op_genkey 挂起。

【问题讨论】:

    标签: c++ encryption gnupg gpgme


    【解决方案1】:

    如果您查看documentation,您会发现gpgme_errot_t 无法与错误代码进行比较:

    ...错误值不能直接与错误代码进行比较,但必须使用下面描述的访问器函数。但是,保证只使用 0 表示成功(GPG_ERR_NO_ERROR),并且在这种情况下,错误值的所有其他部分也都设置为 0。

    error 的值仍然应该为零。这个我帮不了你

    您可以尝试使用gpgme_err_code 找出发生的错误。

    【讨论】:

    • 我更新了我的问题。似乎参数格式错误,但我不知道为什么......
    • 不确定是否有帮助,但请尝试使用 '\n' 而不是空格来分隔参数
    • 尝试在每一行的末尾添加一个“\n”,如下所示:"&lt;GnupgKeyParms format='internal'&gt;\n"
    • 嗯,现在应用程序在 gpgme_op_genkey 处挂起......也许他试图收集“随机数据”但没有完成?或者它确实等待密码输入? (我不知道为什么会这样做,因为我在 XML 字符串中提供了密码)。
    • 挂在什么地方?你能再次以当前形式发布std:string吗?
    【解决方案2】:

    程序在生成密钥时停止,因为系统上可用的熵太少(它是一个 debian VM)。对于可能偶然发现这个问题的其他人:您可以通过查看 /proc/sys/kernel/random/entropy_avail 来了解 debian(和其他 linux 发行版)中可用的熵。我安装了 haveged(在包管理器中可用)并重新运行代码。一切正常。非常感谢mailing list of GnuPG,它帮助我找到了这个解决方案。

    【讨论】:

    • 谢谢!我在 Ubuntu 16.04 中遇到了同样的 keygen 冻结问题。安装haveged 解决了这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-03
    • 1970-01-01
    相关资源
    最近更新 更多