- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我实际上正在研究一个应该从 PKCS7 mime 加密消息中提取 RecipientInfo 的函数。我想这样做的原因是,我想获取邮件加密的所有邮件地址(或至少是 keyids/指纹)。
嗯 - 我尝试了一些东西并创建了这样的东西(indata 是一个 *.p7m 附件内容,indata_len 是 indata 的 strlen):
char *indata;
int indata_len, i;
PKCS7 *p7 = NULL;
BIO *bcont = NULL;
CMS_ContentInfo *cms = NULL;
STACK_OF(CMS_RecipientInfo) *recipients = NULL;
CMS_RecipientInfo *recip = NULL;
BIO *encMessage = BIO_new(BIO_s_mem());
if (encMessage == NULL) {
goto clean_exit;
}
if(!BIO_write(encMessage, indata, indata_len)) {
goto clean_exit;
}
cms = SMIME_read_CMS(encMessage,NULL);
if (cms == NULL ) {
goto clean_exit;
}
recipients = CMS_get0_RecipientInfos(cms);
if (recipients == NULL) {
goto clean_exit;
}
for (i=0; i< sk_CMS_RecipientInfo_num(recipients); i++) {
recip = sk_CMS_RecipientInfo_value(recipients, i);
if( recip == NULL || CMS_RecipientInfo_type(recip) != CMS_RECIPINFO_TRANS ) {
continue;
}
int r;
ASN1_OCTET_STRING **keyid;
X509_NAME **issuer;
ASN1_INTEGER **sno;
r = CMS_RecipientInfo_ktri_get0_signer_id(recip, keyid, issuer, sno);
if (!r) {
continue;
}
printf("Key: %s\n", keyid);
}
我没有得到任何错误(使用 ERR_get_error() 检查)但是 keyid、issuer 和 sno 保持为“null”,以上代码的输出是:
Key: (null)
所以我的问题是,是否有可能获取加密消息的信息,或者我这边的推理是否存在错误?
如果有可能获得该数据,有人可以给我提示吗?如果不可能,那么检查用于解密的私钥的默认(最佳)方法是什么。由于单个用户可以有多个 S/Mime 证书/ key 。例如。创建新 key ,因为旧 key 丢失或只是从提供商那里获得新的证书/ key 组合,...恕我直言,如果消息真的很大,遍历所有键可能需要一些时间。
最好的问候,最大
最佳答案
我不知道如何修复你的代码,但我有几个 openssl
命令和一个 python 脚本来解决你的任务:
您可以运行以下命令来获取所有序列号的列表加密文件 MYMAIL
中的收件人 key :
openssl smime -pk7out -inform DER -in MYMAIL \
| openssl pkcs7 -noout -print \
| grep serial
这会将序列号打印为所有收件人的十进制数字,即文件 MYMAIL
已为其加密的证书的序列号。对于给定的证书文件 CERTFILE.0
,命令
openssl x509 -in CERTFILE.0 -serial -noout
将其序列号打印为十六进制数。现在,您可以将您拥有的证书的序列号与MYMAIL
中提到的序列号结合起来。
我写了一个执行此操作的 python 脚本,可用于替换默认的 smime_decrypt_command在 mutt 中,这样在解密电子邮件时,会选择正确的私钥进行解密:https://github.com/t-wissmann/dotfiles/blob/master/utils/smime-recipient-list.py对于 url 中断的情况,我将在下面粘贴整个脚本。
#!/usr/bin/env python3
"""
Given an smime encrypted file and some smime certificates,
tell for which of the smime certificates, the encrypted file has been
encrypted for.
"""
import argparse
import os
import re
import subprocess
import sys
import textwrap
class Openssl:
def __init__(self, openssl_command):
self.openssl_command = openssl_command
def get_certificate_serial_number(self, certificate_file):
"""Given a certificate_file filepath, return its serial number as an int"""
command = [self.openssl_command, 'x509', '-in', certificate_file, '-serial', '-noout']
proc = subprocess.run(command, stdout=subprocess.PIPE)
# output should be of the form 'serial=HEXADECIMALNUMBER'
try:
return int(proc.stdout.decode().replace('serial=', ''), 16)
except ValueError:
print("Can not read file: {}".format(certificate_file), file=sys.stderr)
def smime_pk7out(self, encrypted_file):
"""run smime -pk7out, return its output"""
command = [self.openssl_command, 'smime', '-pk7out']
command += ['-inform', 'DER', '-in', encrypted_file]
proc = subprocess.run(command, stdout=subprocess.PIPE)
return proc.stdout.decode()
def pkcs7_serial_numbers(self, pk7buf):
"""extract all serial numbers via openssl pkcs7 -noout -print"""
command = [self.openssl_command, 'pkcs7', '-noout', '-print']
proc = subprocess.run(command, stdout=subprocess.PIPE, text=True, input=pk7buf)
for match in re.finditer('serial: ([0-9]+)', proc.stdout):
yield int(match.group(1))
def list_recipient_serial_numbers(self, encrypted_file):
"""Do essentially:
openssl smime -pk7out -inform DER -in MYMAIL \
| openssl pkcs7 -noout -print \
| grep serial
"""
pk7out = self.smime_pk7out(encrypted_file)
return list(self.pkcs7_serial_numbers(pk7out))
def smime_decrypt(self, private_key, certificate, filepath, passin='stdin'):
"""encrypt the given filepath and print to stdout"""
command = [self.openssl_command, 'smime', '-decrypt', '-passin', passin]
command += ['-inform', 'DER', '-in', filepath]
command += ['-inkey', private_key]
command += ['-recip', certificate]
subprocess.run(command)
def main():
"""main"""
description = "Detect recipients of smime encrypted files"
epilog = textwrap.dedent(r"""
E.g. you can decrypt an email with the command that picks the
private key automatically:
{} \
--passin stdin --decrypt \
--private-key ~/.smime/keys/* \
-- mymail ~/.smime/certificates/*
If you use mutt, you can set
set smime_decrypt_command="\
~/path/to/smime-recipient-list.py --passin stdin --decrypt \
--private-key ~/.smime/keys/* \
-- %f ~/.smime/certificates/KEYPREFIX.*"
where KEYPREFIX is the prefix of your key (i.e. without the .0 or .1 suffix).
""".format(sys.argv[0]))
parser = argparse.ArgumentParser(
description=description,
epilog=epilog,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('encryptedfile', help='the encrypted file')
parser.add_argument('certificates',
nargs='+',
help='the smime certificate files')
parser.add_argument('--openssl', default='openssl', help='openssl command name')
parser.add_argument('--list-serials', action='store_true',
help='list serial numbers of certifacts')
parser.add_argument('--print-path', action='store_true',
help='print path of recipient certificates')
parser.add_argument('--private-keys', nargs='*', default=[], help='private keys for decrypt')
parser.add_argument('--decrypt', action='store_true',
help='decrypt using one of the private keys passed.\
the key must have the same file name as the certificate.')
parser.add_argument('--passin', default='stdin',
help='default openssl -passin parameter for decrypt')
args = parser.parse_args()
openssl = Openssl(args.openssl)
# get the serial number of every smime-certfile:
serialnum2cert = {}
for i in args.certificates:
serialnum2cert[openssl.get_certificate_serial_number(i)] = i
if args.list_serials:
for serialnum, keyfile in serialnum2cert.items():
print("{} --> {}".format(keyfile, serialnum))
recipients = openssl.list_recipient_serial_numbers(args.encryptedfile)
if args.print_path or args.decrypt:
matching_keys = []
for i in recipients:
if i in serialnum2cert:
matching_keys.append(serialnum2cert[i])
if args.print_path:
for i in matching_keys:
print(i)
if args.decrypt:
private_keys = {}
for filepath in args.private_keys:
private_keys[os.path.basename(filepath)] = filepath
key_found = None
for fp in matching_keys:
if os.path.basename(fp) in private_keys:
priv_key_path = private_keys[os.path.basename(fp)]
# print("We can use {} and {}".format(priv_key_path, fp))
key_found = (priv_key_path, fp)
if key_found is None:
print("No matching private key found.", file=sys.stderr)
sys.exit(1)
openssl.smime_decrypt(key_found[0], key_found[1],
args.encryptedfile, passin=args.passin)
if __name__ == "__main__":
main()
关于CMS (PKCS#7) 收件人信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21290975/
常用的 PKCS 标准有什么用:PKCS#7、PKCS#10 和 PKCS#12? 最佳答案 PKCS#7 允许您使用 X.509 证书对通用数据进行签名和加密。 PKCS#7 格式也可用于存储一个或
我想知道当使用 AES-128-CBC 时,openssl 如何处理可被 8 个字节整除的消息。 openssl 如何检测到没有要删除的填充(PKCS#5/PKCS#7)?特别是当消息以 ASCII
我正在阅读 PKCS 11 文档,但我无法清楚地理解 key 的 CKA_SENSITIVE 属性是什么意思。 更常见的是:我在哪里可以阅读属性描述? 最佳答案 引自 PKCS#11 spec v2.
我想寻求有关使用 cryptography.hazmat.primitives.padding.PKCS7 的帮助Python 类。 解密后,我得到字符串45394700000019770808080
我知道 PKCS#7 = 证书 + 可选原始数据 + PKCS#1 格式的签名 我需要从 PKCS#7 签名中提取 PKCS#1 如何在 C# 中执行此操作。我可以用充气城堡来做这个吗,这是我的实现I
我希望能够使用带有 aws golang SDK 的 AWS SNS 发送 iOS APNS 推送通知。我按照以下说明创建了一个 p12 文件:https://support-aws.s3.amazo
关闭。这个问题需要更多focused .它目前不接受答案。 想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post . 2年前关闭。 Improve this questi
我正在开发一个移动应用程序,它必须验证它收到的一些签名。我拥有我需要的一切——输入数据、公钥和签名。但有一个问题。我使用方法 SHA256withRSA 进行签名验证,其中包含以下几行代码来验证签名:
我有一个 PKCS#5 加密的 PKCS#8 RSA 私钥存储在一个磁盘文件中(最初由 SSLPlus 生成,大约在 1997 年),例如: -----BEGIN ENCRYPTED PRIVATE
是否可以将 PKCS#8 编码的 RSA 私钥转换为 PKCS#1?我知道这可以通过 openssl 轻松完成,但是可以用 Java 完成吗? 最佳答案 使用 BouncyCaSTLe 1.50 Pr
我正在为 Android 实现 Jscep。最初,我尝试了 Jscep for java,效果很好。现在在 Android 中,我使用 SpongyCaSTLe 而不是 BouncyCaSTLe。现在
我正在尝试在 SafeNet HSM 中生成一个 RSA key 对。我为私钥和公钥复制了 PKCS11 中指定的示例模板。当我生成 key 对时,一切正常。但是,当我为私钥指定以下属性值时,C_Ge
密码学在信息安全中扮演着至关重要的角色。为了保护敏感信息、数字身份和网络通信的安全性,密码设备(如硬件安全模块HSM)与应用程序之间的安全通信和互操作性变得至关重要。PKCS#11(Public-K
这玩意折腾了一天,有个老外的代码,公钥用了PKCS#1,私钥用了PKCS#8。调用了不同的API,而我的全是生成的PKCS#8,后面查阅了大量资料和长时间调试程序,才发现了问题,在此记录下。 用Ope
PKCS#12是一种将私钥与其对应的 X.509 证书合并为标准化的单一文件格式的便捷方式。然而,该规范于 1999 年由 RSALabs 发布,并且仅使用 RC4、RC2 和 TripleDES 进
我正在尝试使用 PKCS#7 进行签名和验证签名。我正在阅读《beginning cryptography with java》这本书。我已经编写了示例代码来签名和验证。当我尝试附加签名并将其写入文件
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 4年前关闭。 Improve this qu
使用java加密、签名、解密、验证签名需要遵循哪些步骤? 使用 PKCS#7 算法, java keystore 有什么用?关于 PKCS#7。 最佳答案 第 1 步 使用 keytool 实用程序生
我在 iPhone 上使用这个 OpenSSL 代码生成一个 PKCS#12 文件,给定证书/私钥的一些数据。我能够验证此 PKCS#12 在 OpenSSL 上是否可解析,因为当我在代码中检查它时它
我实际上正在研究一个应该从 PKCS7 mime 加密消息中提取 RecipientInfo 的函数。我想这样做的原因是,我想获取邮件加密的所有邮件地址(或至少是 keyids/指纹)。 嗯 - 我尝
我是一名优秀的程序员,十分优秀!