2011-11-01 95 views
1

我正在使用Lion和Xcode 4.1。SecKeyRawSign osx与EC证书

SecKeyRawSign没有记录在OSX中,但它仍然可以被调用并成功地为RSA证书签名,但是EC证书失败。

SecKeyRawSign方法返回-50,即ec cert-384的无效参数。

SecKeyRawSign可以用于OSX和EC Cert吗?如果是,那么填充参数是什么?

在此先感谢。

回答

4

SecKeyRawSign是Mac OS 10.6和10.7中的一个私有函数,所以你不应该使用它。它与ECC证书有关的问题可能只是其尚未公开的原因之一。

10.7中用于数据签名的官方高级API是SecSignTransformCreateSecurity Transforms。它应该自动使用合适的摘要算法;如果不是的话,你只需设置kSecDigestTypeAttributekSecDigestLengthAttribute即可。 AFAIK填充算法不可配置。

在10.6或更低版本中,您必须使用CDSA。首先,您使用CSSM_CSP_CreateSignatureContext创建一个上下文。签名算法是CSSM_ALGID_SHA512WithECDSA(或相似);您可以从SecKeyGetCSPHandle,SecKeyGetCSSMKeySecKeyGetCredentials中获得其他参数。签署上下文后,您可以使用CSSM_SignData对您的数据进行签名。摘要算法应该是CSSM_ALGID_NONE

填充最好由Thomas Pornin的answer to another question解释。

+0

感谢您的回复。 –

2

@Fnord

感谢您的回复。我写了以下代码:

CFDataRef 
CreateSignature (SecKeyRef privateKeyRef, CFDataRef plaintext, CFErrorRef &error) 
{ 
    SecTransformRef signingTransform = SecSignTransformCreate(privateKeyRef, error); 
    if (signingTransform == NULL) 
     return NULL; 

    Boolean success = SecTransformSetAttribute(signingTransform, 
               kSecTransformInputAttributeName, 
               plaintext, 
               error); 
    if (!success) { 
     CFRelease(signingTransform); 
     return NULL; 
    } 

    CFDataRef signature = SecTransformExecute(signingTransform, error); 
    CFRetain(signature); 
    CFRelease(signingTransform); 
    return signature; 
} 
+0

我编辑了你的代码以使其工作。几点要点: (1)除非另有说明(在InputIs属性中),否则签名转换的输入是要签名的明文,而不是其摘要。转换将自动选择适当的摘要算法,或者您可以在DigestType/DigestLength属性中提供一个。 (2)不要忘记实际执行您创建的转换。 (3)**总是**在您创建或复制的对象上调用CFRelease。 (4)检查所有返回值,错误始终发生。 –

+0

一个巨大的警告:如果您的应用程序没有使用私钥签名数据的证书(例如,如果用户在Keychain的确认对话框中拒绝访问),则“SecTransformExecute”不会报告错误,但会默默产生虚假数据。 (看起来它会返回一个填充垃圾的32768字节的内部缓冲区。) –