2 Replies
      Latest reply on Nov 6, 2019 6:19 PM by Lemiyon
      craigaps Level 1 Level 1 (0 points)

        Hi

         

        I'm trying to use SecKeyCreateSignature to sign a string but seem to have missed something.  Here is my code snippet:

         

        public static func sign(using name: String, value: String, base64EncodingOptions: Data.Base64EncodingOptions = []) -> String?
        {
            // Get private key by name using SecItemCopyMatching
            guard let privateKey: SecKey = getPrivateKey(name) else
            {
                return nil
            }
        
            let data = value.data(using: .utf8)!
             
            var error: Unmanaged<CFError>?
            guard let signedData = SecKeyCreateSignature(privateKey,
                                                            .rsaSignatureDigestPKCS1v15SHA512,
                                                            data as CFData,
                                                            &error) as Data? else
            {
                return nil
            }
           
            return signedData.base64EncodedString(options: base64EncodingOptions)
        }
        
        

         

        And to call the method:

        let result = sign("MyKey", "hello world")
        print(result)
        
        

         

         

        Using the public key generated on iOS and exported to Java, the validation fails.  I'm think it might be something to do with value.data(using: .utf8) but I'm not sure.  Using the older style SecKeyRawSign you would hash the "hello world" value before invoking SecKeyRawSign

         

        Any ideas or a simple example would be great

        • Re: Sign a String with SecKeyCreateSignature
          craigaps Level 1 Level 1 (0 points)

          I figured out the probem.  I thought it had to do with line 9. of the snippet where I'm creating the data variable.  It turned out to be the algorithm paramter in line 12.  From the snippet I was passing in rsaSignatureDigestPKCS1v15SHA512, when what I should have been passing in was rsaSignatureMessagePKCS1v15SHA512.

           

          After updating the parameter, small and large string values are now working and can be verified against my public key.  Below is the updated function:

           

          public static func sign(using name: String, value: String, base64EncodingOptions: Data.Base64EncodingOptions = []) -> String?
          {
              /
              guard let privateKey: SecKey = getPrivateKey(name) else
              {
                  return nil
              }
             
              let data = value.data(using: .utf8)!
             
              var error: Unmanaged<CFError>?
              guard let signedData = SecKeyCreateSignature(privateKey,
                                                           .rsaSignatureMessagePKCS1v15SHA512,
                                                           data as CFData,
                                                           &error) as Data? else
              {
                  return nil
              }
          }
          

           

          Hope this helps.