Friday, 7 July 2023

Byte difference between python cryptography and JS Forge when making pkcs #7 signing

I am needing to connect to AirWatch API with pkcs 7 signed data for security.

On this page I found a sample of how to make the connection in python, and this works correctly when I provide my certificate and key files. Here is a sample of using the cryptopgraphy library using a generic certificate and key for testing:

import base64
from cryptography.hazmat.primitives.serialization import pkcs12, pkcs7
from cryptography.hazmat.primitives import hashes, serialization
import requests

signing_data = "/api/mdm/devices/search" # the part of the url to be signed

certfile = open("/home/claude/certificate.p12", 'rb')
cert = certfile.read()
certfile.close()


#p12 format holds both a key and a certificate
key, certificate, additional_certs = pkcs12.load_key_and_certificates(cert, "motdepasse".encode())

#print (certificate.subject)
#print (key)

pem = key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.TraditionalOpenSSL,
    encryption_algorithm=serialization.NoEncryption()
)

options = [pkcs7.PKCS7Options.NoCapabilities,  pkcs7.PKCS7Options.DetachedSignature]

signed_data = pkcs7.PKCS7SignatureBuilder().set_data(
    signing_data.encode("UTF-8"))

signed_data = signed_data.add_signer(certificate, key, hashes.SHA256())

signed_data = signed_data.sign(serialization.Encoding.DER, options)

print(signed_data)

For

and here is an sample of the byte output converted to UTF-8. I can use this signed data to connect to the AirWatch API correctly:

0Ç D    *ÜHܘ
   †Ç 50Ç 1   1 0
    `ÜH e      0    *ÜHܘ
   †Ç  0Ç  0Ç ˘    (ƒ'±M
–1ï◊ÌÛ«õR ]µ0
    *ÜHܘ
     0E1 0    U    AU1 0   U   
Some-State1!0   U 
  Internet Widgits Pty Ltd0  
230531184611Z 
230829184611Z0E1 0    U    AU1 0   U   
Some-State1!0   U 
  Internet Widgits Pty Ltd0Ç "0
    *ÜHܘ
      Ç   0Ç 
 Ç   ÷ü$’% I        ∞ˆv∆ ºe_Ö4*Úˇ ≥Ì‘ {≈i‰Aı C>˘Ã\åZÔu€óŒ7£V9DÇ fr ˜uô ≠í
‹%nˇòg^∞ñÁ —˝Î ÒW &ììl‡û∏`± ´  ä‹ÖpO‰-n “æ∆È >î=ÈØπÌ  xcï¢Ñ«ˇo‚ ¬¬ ¸1 8 &cqë yÛÇ®tB ùé%ªy ˛5É≈  ŸπÎT êπ¯„?C'*(v ºª
·r®µ≤µ8 V   C…›wÑb¢n¿Éµ÷ß∏-7ÚqÑE Û2‹F /E®ñ5 üj>»¶&∆˙ôî˝¡Agå≥˘V˘ ñ"‹flA⁄Ñ·¯ ^   "%     0
    *ÜHܘ
      Ç   ¡Íà ˘\7T
9 s¿˛‚L4î6  ¶Säπ:È[Q}˝œ≠R§Cß=  ‹• ¥¸œ9É]o˝ iÅ\B)7n ≈©“Úò √F‘‚¥Œ• I≤^Fá≥¡v9R  a%  Í V ~y5 ®≠—_vø Jë>a}°8èj$Ü5  Éî’êµ<® ˙ÅåwÏò≠´6ªâ[◊NèQ‚ú  GG´˛uoN¸€óª ªˇçðs;Ε Ô2Ò+Æ ∫"_ä
1P≈†ß…çø∆yû  QöRtm= ƒÙ ÔßsÏ
∆≈∞ ™fl„¡r <ÑkxÓhª rZú‡6 Xı“´‘”æE '3U≈èˇÕá™ U%1Ç Û0Ç Ô   0]0E1 0   U    AU1 0   U   
Some-State1!0   U 
  Internet Widgits Pty Ltd    (ƒ'±M
–1ï◊ÌÛ«õR ]µ0
    `ÜH e      †i0      *ÜHܘ
     1      *ÜHܘ
   0    *ÜHܘ
     1  
230618112934Z0/     *ÜHܘ
     1"  SnÄ∞ïÓoDW≤NiÅ ËKéA 8ÈA„wø œ‘?p’ˆ0
    *ÜHܘ
      Ç   éü≠6 õ  ÷ÚˆÂûÛñI<2‡¿ıp∞$Bfl‹‹Óµ  ?Ü—s Ökû0s#y û˚•£îc· ù,4∆≠ë1Á§  ˙ F$ Û:n{$£Á?ÎKDΩ˜™êÛJCp v æ7H
ÉaâS^äjm“ÓK‘≠:Ëàp ÆéQ©Õ4≥∫ `˛`9 TÓa xYz]z‹–-·qÖ$E7Mvøuà äâq°Ú@LVPT3=—÷íTÍG√ Ì˘1j Eû']◊b” flèo)d?˚9Æ:íd%y€Îªë=ø5ZlÄ2πËãöN•*K  a#›·hD› ̸qò§Ω¨™r-H 3”2OwÄg»-π…6KI[

now I would like to use this in javscript. here is my code using forge-js:

function withPem() {
  var signing_data = "/api/mdm/devices/search"; // the part of the url to be signed
  var keyAndCert = getKeyAndCert()
  var key = keyAndCert.key;
  var cert = keyAndCert.cert;

  options = {}

  options['detached'] = true
  options['certificate'] = forge.pkcs7.OID_CAPABILITY_NONE
  var p7 = forge.pkcs7.createSignedData(options=options);
  p7.content = forge.util.createBuffer(signingData, 'utf8');

  p7.addCertificate(cert);
  p7.addSigner({
    key: key,
    certificate: cert,
    digestAlgorithm: forge.pki.oids.sha256,
    authenticatedAttributes: [{
            type: forge.pki.oids.contentType,
            value: forge.pki.oids.data,
        }, 
        {
            type: forge.pki.oids.messageDigest
        }, 
        {
            type: forge.pki.oids.signingTime, 
            value: new Date()
        }]
  });



  var signed = p7.sign({ detached: true })
  
  var bufferOut = forge.asn1.toDer(p7.toAsn1()).getBytes();

}

but when I provide the the same key and certificate, the output is very very similar but not the same:

0_  *H÷
 P0L10
    `He�0&  *H÷
 /api/mdm/devices/search 00ù (Ä'±M
Ð1×íóÇR]µ0
    *H÷
�0E10   UAU10U
Some-State1!0U
Internet Widgits Pty Ltd0
230531184611Z
230829184611Z0E10   UAU10U
Some-State1!0U
Internet Widgits Pty Ltd0"0
    *H÷
��0
�Ö$Õ%I      °övƼe_4*òÿ³íÔ{ÅiäAõC>ùÌ\ZïuÛÎ7£V9Dfr÷u­
Ü%nÿg^°çÑýëñW&là¸`±«ÜpOä-nÒ¾ÆéÊ>=鯹íxc¢ÇÿoâÂÂü18&cqyó¨tB%»yþ5ÅÙ¹ëTʹøã?C'*(v¼»
ár¨µ²µ8V    CÉÝwb¢nÀµÖ§¸-7òqEó2ÜF/E¨5j>Ȧ&ÆúýÁAg³ùVù"ÜßAÚáø^"%�0
    *H÷
��ÁêÌè÷\7T
9sÀþâL46¦S¹:é[Q}ýÏ­R¤C§=ÊÜ¥´üÏ9]oýi\B)7nÅ©ÒòÃFÔâ´Î¥I²^F³Áv9ðR a%êV~y5¨­Ñ_v¿J>a}¡8j$ð5Õµ<¨úwì­«6»[×NQâGG«þuoNüÛ»»ÿÌ¡s;ë¥ï2ñ+®º"_
1PÅ §É¿ÆyQRtm=Äôï§sì
ÆÅ°ªßãÁr<kxîh»ÊrZà6 XõÒ«ÔÓ¾E'3UÅÿͪU%1ó0ï0]0E10 UAU10U
Some-State1!0U
Internet Widgits Pty Ltd (Ä'±M
Ð1×íóÇR]µ0
    `He� i0 *H÷
    1   *H÷
0/  *H÷
    1" Sn°îoDW²NièKA8éAãw¿ÏÔ?pÕö0   *H÷
    1
230626090435Z0
    *H÷
��s4Q ±cPC%¯[óBÚà Q3¶ZF°'Úø?öÌôÁËñ¨+7"¬áÜtÒ1N�ñÞ&@áKÓ@a[5[¶ú)ãë#µÈN¾²Ç GE!eQ²H×=ÜwÂ)ÛÕ8=êÿÈPz1;m=ÕPi[®
{?¥NñÎ:7 ·ó@q![k|þûú~ÞÏZº>S-¼º¼Ù/ܾíg{}>mé;RmÀ!S:öÒã8ê¬Ð§KêGFv¿Üq~ÅÅ®r].àK]¼Ý¼dzlußø5³ÀON

I can't find anything that I am going wrong with the forge package but the output does not work with the API. Is there a difference between the way forge does pkcs7 signing compared to cryptography in python? what can I do to fix this js code? unfortunately I need to use Js because that is the requirement i have been given

thank you in advance :)



from Byte difference between python cryptography and JS Forge when making pkcs #7 signing

No comments:

Post a Comment