@@ -101,9 +101,10 @@ def get_public_key(private_key)
101101 # @param private_key [String] private key, format: binary string
102102 # @param data [String]
103103 # @param sm3_hash [Boolean], option to sign with sm3 hash, default: false
104- # @param user_id [String], format: hex string, default: "31323334353637383132333435363738"
104+ # @param user_id [String], format: hex string, default: "31323334353637383132333435363738" which is equal to utf-8 str "1234567812345678"
105+ # @param asn1 [Boolean], option to return asn.1 der format signature, default: false
105106 # @return [String] signature, format: hex string
106- def sign ( private_key , data , sm3_hash : false , user_id : "31323334353637383132333435363738" )
107+ def sign ( private_key , data , sm3_hash : false , user_id : "31323334353637383132333435363738" , asn1 : false )
107108 data = data . unpack1 ( "a*" ) unless data . ascii_only?
108109 if sm3_hash
109110 public_key = get_public_key ( private_key )
@@ -130,7 +131,11 @@ def sign(private_key, data, sm3_hash: false, user_id: "3132333435363738313233343
130131 s = ( ( one + da ) . mod_inverse ( n ) * ( k - ( r * da ) ) ) . to_i % n . to_i
131132 end
132133
133- r . to_s ( 16 ) . rjust ( 64 , "0" ) + s . to_s ( 16 ) . rjust ( 64 , "0" )
134+ if asn1
135+ OpenSSL ::ASN1 ::Sequence . new ( [ OpenSSL ::ASN1 ::Integer . new ( r ) , OpenSSL ::ASN1 ::Integer . new ( s ) ] ) . to_der . unpack1 ( "H*" )
136+ else
137+ r . to_s ( 16 ) . rjust ( 64 , "0" ) + s . to_s ( 16 ) . rjust ( 64 , "0" )
138+ end
134139 end
135140
136141 # verify the signature with public_key
@@ -140,17 +145,28 @@ def sign(private_key, data, sm3_hash: false, user_id: "3132333435363738313233343
140145 # @param signature [String], hex string
141146 # @param sm3_hash [Boolean], option to sign with sm3 hash, default: false
142147 # @param user_id [String], format: hex string, default: "31323334353637383132333435363738"
148+ # @param asn1 [Boolean], option to verify asn.1 der format signature, default: false
143149 # @return [Boolean] verify result
144- def verify ( public_key , data , signature , sm3_hash : false , user_id : "31323334353637383132333435363738" )
145- return false if signature . size != 128
150+ def verify ( public_key , data , signature , sm3_hash : false , user_id : "31323334353637383132333435363738" , asn1 : false )
151+ if asn1
152+ # return false if signature.size < 138
153+
154+ # parse asn1 der format hex string signature
155+ der_seq = OpenSSL ::ASN1 . decode ( [ signature ] . pack ( "H*" ) )
156+ r = der_seq . value [ 0 ] . value
157+ s = der_seq . value [ 1 ] . value
158+ else
159+ return false if signature . size != 128
160+
161+ r = OpenSSL ::BN . new ( signature [ 0 , 64 ] , 16 )
162+ s = OpenSSL ::BN . new ( signature [ 64 , 64 ] , 16 )
163+ end
146164
147165 public_key = "\x04 #{ public_key } " if public_key . size == 64 && public_key [ 0 ] != "\x04 "
148166 data = data . unpack1 ( "a*" ) unless data . ascii_only?
149167 if sm3_hash
150168 data = OpenSSL ::Digest . digest ( "SM3" , za ( public_key , user_id ) + data )
151169 end
152- r = OpenSSL ::BN . new ( signature [ 0 , 64 ] , 16 )
153- s = OpenSSL ::BN . new ( signature [ 64 , 64 ] , 16 )
154170 n = OpenSSL ::BN . new ( "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123" , 16 )
155171 e = OpenSSL ::BN . new ( data , 2 )
156172
0 commit comments