自动将PEM文件拆分为多个Certs

时间:2014-07-31 21:58:41

标签: batch-file ssl scripting openssl certificate

我需要找到一种方法来自动化将PEM文件拆分为多个PEM文件的过程。我正在考虑使用一个批处理脚本,它会在每次找到时抓住PEM和Separate:

  

----- BEGIN CERTIFICATE -----

  

----- END CERTIFICATE -----

然而,这似乎有点“hacky”。我希望OpenSSL有一个可以做到这一点的工具,但我似乎无法找到任何东西。

这样做的最佳方式是什么?

2 个答案:

答案 0 :(得分:1)

  

我希望OpenSSL有一个可以做的工具

我不知道OpenSSL功能或OpenSSL工具。查看来源,PEM_bytes_read_bio 可能是执行此操作的功能。但它没有记录,所以我不确定。 (函数名称以capitol字母开头 - PEM_* 。各种低位字母 - pem_* 是私有的,不应使用。

如果您有OpenSSL sources方便,则解析例程的源代码位于<openssl src>/crypto/pem/pem_lib.c。那就是实现PEM_bytes_read_bio的地方。


  

然而,这似乎有点&#34; hacky。&#34;

嗯,它不是那么多hacky - 你必须卷起袖子并编码。您可以使用Bison和Flex创建解析器和词法分析器。你如何从shell中调用它是一个不同的故事。使用词法分析器,我认为您可以在 O(n)中解析PEM对象。


  

我需要找到一种方法来自动化将PEM文件拆分成多个PEM文件的过程......这样做的最佳方法是什么?

我在PEM Pack写了类似的Crypto ++。它增加了对PEM编码密钥的支持,包括加密密钥。 Crypto ++是一个C ++库,但相同的通用算​​法应该适合您选择的语言。

Crypto ++中感兴趣的例程称为PEM_NextObject,它位于源文件pem-rd.cpp中。您可以在ZIP文件中找到页面底部的源文件。 PEM_NextObject寻找了四个项目:

  • 领先-----BEGIN
  • 以下-----
  • 尾随-----END
  • 以下-----

我使用了四个索引 - 每个令牌一个。我会一次读取64 + 1个字节,因为OpenSSL以64个字符输出它的中断。我会读一行string并将字符串连接到累加器。然后我会使用find在累加器中找到令牌(有些人放弃了,因为它们是安全的字符串)。如果我没有找到特定索引,我会读另一行。

搜索令牌时,第一个令牌的搜索从位置0开始。下一个搜索在找到上一个索引后开始。例如,搜索索引2从索引1开始加上令牌的大小;搜索索引3从索引2开始加上令牌的大小。如果找不到令牌,我只搜索当前行,并且在令牌跨越先前读取和当前读取的情况下继续搜索10个字符。

我使用索引而不是迭代器,因为如果容器的大小增加,迭代器将失效。串联会导致这种情况。幸运的是,索引始终有效,因为它只是从字符串开头的偏移量。你可能没有bash(或任何你选择的)这个问题。

如果我在没有找到所有四个索引的情况下读到流的末尾,那么我就抛出了一个错误。

如果我找到了所有四个索引,那么我有一些声称是PEM编码的东西。我丢弃了任何前导字符,并修剪了尾随空格。因此,PEM对象位于(Index1)(Index4 + 5)(后跟-----为+5)。

因为我可能已经解析了无效的PEM对象(即-----BEGIN FOO----------END BAR-----),所以我需要另一个例程来对已解析的PEM对象的类型进行分类。该函数称为PEM_GetType

该算法应该运行良好,因为从算法分析的角度来看它并不是很奇怪,而且PEM对象通常很小(小于2K或4K)。我认为分析是 O(n + m * 10),其中m是文件中的行数。 m * 10基于扫描64个字符的行,查找具有10个字符&#34;倒带&#34;的令牌,读取另一行,然后再次扫描令牌。回想一下我&#34;倒带&#34;有点以防令牌跨越线。

如果没有PEM对象并且文件很大,则此算法执行OK。我确定它在 O(n + m * 10)中运行的情况也更糟糕。 如果 n >>> m,那么它本质上是 O(n)函数,因为m*10只是一个大的边界c

您可能也对服务器故障上的How to split a PEM file和Stack Overflow上的Where is the PEM file format specified?感兴趣。


  

-----开始证书-----到-----结束证书-----

显示证书时,还有其他类型的对象。例如,公钥和加密的私钥。 如果您需要解密加密密钥,那么您需要解除/借用/使用OpenSSL EVP_BytesToKey

EVP_BytesToKey是一种非标准的,因此它成为一种复制/粘贴操作,以确保互操作性。我似乎记得EVP_BytesToKey等同于PKCS#5派生 如果 EVP_BytesToKey生成的字节数为16或更少。如果产生17个或更多,那么OpenSSL使用&#34;非标准&#34;扩展


如果您对测试感兴趣,请查看pem-create-keys.sh。它会创建格式错误的PEM编码密钥(而不是证书)。例如,它将连接多个没有换行符的键,它将删除其中一个尾部短划线,它将删除其中一个尾随破折号,然后连接另一个键。

答案 1 :(得分:0)

我遇到了类似的问题,csplit 似乎很合适。

以下一行代码查找 -----BEGIN 模式并根据它(任意次数)拆分为单独的文件:

$ csplit -sz private.pem '/.*BEGIN/' '{*}'