json signing wip tests
Object after signature
{
"type": "attack-pattern",
"id": "attack-pattern--2a8ec2a9-44e2-490c-8045-5a88ef89302f",
"created": "2018-11-23T20:44:31.418Z",
"modified": "2018-11-26T20:44:31.418Z",
"revoked": false,
"object_marking_refs": [
"marking-definition--72f07c91-87d2-44a1-bf16-29fc935936c0"
],
"granular_markings": [
{
"selectors": [
"pattern1",
"pattern2",
"pattern3"
],
"marking_ref": "marking-definition--d3b09fa4-55aa-4d47-abe0-b3a00eecd0df"
}
],
"name": "some pattern",
"kill_chain_phases": [
{
"kill_chain_name": "Chain1",
"phase_name": "phase1"
},
{
"kill_chain_name": "Chain1",
"phase_name": "phase2"
}
],
"x_signed_object": "eyJhbGciOiJIUzI1NiJ9.eyJ0eXBlIjoiYXR0YWNrLXBhdHRlcm4iLCJpZCI6ImF0dGFjay1wYXR0ZXJuLS0yYThlYzJhOS00NGUyLTQ5MGMtODA0NS01YTg4ZWY4OTMwMmYiLCJjcmVhdGVkIjoiMjAxOC0xMS0yM1QyMDo0NDozMS40MThaIiwibW9kaWZpZWQiOiIyMDE4LTExLTI2VDIwOjQ0OjMxLjQxOFoiLCJyZXZva2VkIjpmYWxzZSwib2JqZWN0X21hcmtpbmdfcmVmcyI6WyJtYXJraW5nLWRlZmluaXRpb24tLTcyZjA3YzkxLTg3ZDItNDRhMS1iZjE2LTI5ZmM5MzU5MzZjMCJdLCJncmFudWxhcl9tYXJraW5ncyI6W3sic2VsZWN0b3JzIjpbInBhdHRlcm4xIiwicGF0dGVybjIiLCJwYXR0ZXJuMyJdLCJtYXJraW5nX3JlZiI6Im1hcmtpbmctZGVmaW5pdGlvbi0tZDNiMDlmYTQtNTVhYS00ZDQ3LWFiZTAtYjNhMDBlZWNkMGRmIn1dLCJuYW1lIjoic29tZSBwYXR0ZXJuIiwia2lsbF9jaGFpbl9waGFzZXMiOlt7ImtpbGxfY2hhaW5fbmFtZSI6IkNoYWluMSIsInBoYXNlX25hbWUiOiJwaGFzZTEifSx7ImtpbGxfY2hhaW5fbmFtZSI6IkNoYWluMSIsInBoYXNlX25hbWUiOiJwaGFzZTIifV0sInhfc29tZUN1c3RvbUtleSI6Ik15IGN1c3RvbSB2YWx1ZSIsInhfc29tZU90aGVyQ3VzdG9tX2tleSI6MzkzOX0.6BEzPVqG3aeK4bEB7JvKR_tJENpvKwH8_NR711maGog",
"x_someCustomKey": "My custom value",
"x_someOtherCustom_key": 3939
}
Object has been encoded and signed into the object it self. Someone can load each object and compare the individual values. They can also remove the x_signed_object property in the original, and then compare.
If we look at the signed object:
{
"type": "attack-pattern",
"id": "attack-pattern--2a8ec2a9-44e2-490c-8045-5a88ef89302f",
"created": "2018-11-23T20:44:31.418Z",
"modified": "2018-11-26T20:44:31.418Z",
"revoked": false,
"object_marking_refs": [
"marking-definition--72f07c91-87d2-44a1-bf16-29fc935936c0"
],
"granular_markings": [
{
"selectors": [
"pattern1",
"pattern2",
"pattern3"
],
"marking_ref": "marking-definition--d3b09fa4-55aa-4d47-abe0-b3a00eecd0df"
}
],
"name": "some pattern",
"kill_chain_phases": [
{
"kill_chain_name": "Chain1",
"phase_name": "phase1"
},
{
"kill_chain_name": "Chain1",
"phase_name": "phase2"
}
],
"x_someCustomKey": "My custom value",
"x_someOtherCustom_key": 3939
}
encoded: eyJhbGciOiJIUzI1NiJ9.eyJ0eXBlIjoiYXR0YWNrLXBhdHRlcm4iLCJpZCI6ImF0dGFjay1wYXR0ZXJuLS0yYThlYzJhOS00NGUyLTQ5MGMtODA0NS01YTg4ZWY4OTMwMmYiLCJjcmVhdGVkIjoiMjAxOC0xMS0yM1QyMDo0NDozMS40MThaIiwibW9kaWZpZWQiOiIyMDE4LTExLTI2VDIwOjQ0OjMxLjQxOFoiLCJyZXZva2VkIjpmYWxzZSwib2JqZWN0X21hcmtpbmdfcmVmcyI6WyJtYXJraW5nLWRlZmluaXRpb24tLTcyZjA3YzkxLTg3ZDItNDRhMS1iZjE2LTI5ZmM5MzU5MzZjMCJdLCJncmFudWxhcl9tYXJraW5ncyI6W3sic2VsZWN0b3JzIjpbInBhdHRlcm4xIiwicGF0dGVybjIiLCJwYXR0ZXJuMyJdLCJtYXJraW5nX3JlZiI6Im1hcmtpbmctZGVmaW5pdGlvbi0tZDNiMDlmYTQtNTVhYS00ZDQ3LWFiZTAtYjNhMDBlZWNkMGRmIn1dLCJuYW1lIjoic29tZSBwYXR0ZXJuIiwia2lsbF9jaGFpbl9waGFzZXMiOlt7ImtpbGxfY2hhaW5fbmFtZSI6IkNoYWluMSIsInBoYXNlX25hbWUiOiJwaGFzZTEifSx7ImtpbGxfY2hhaW5fbmFtZSI6IkNoYWluMSIsInBoYXNlX25hbWUiOiJwaGFzZTIifV0sInhfc29tZUN1c3RvbUtleSI6Ik15IGN1c3RvbSB2YWx1ZSIsInhfc29tZU90aGVyQ3VzdG9tX2tleSI6MzkzOX0.6BEzPVqG3aeK4bEB7JvKR_tJENpvKwH8_NR711maGog
Key used to encode using HS256: srYdIZO5Yg/3BhRbzFOWB6cEcmtiLbyp0tS/OeLDP0w=
In practice you would implement Public/Private key JWT, so you can share the public key with consumers.
Showing on jwt.io:


A API response could also be to just expose objects as signed strings to which are decoded by the consumer.
and if we add some header information:

Header information can be used to determine the public key source that is cross-referenced in the by the consumer and validates that the source location is part of the "approved/trusted list".
Distributors could also allow consumers to request new copies of CTI STIX data with updated signatures. This allows the possibility of expiring data where the copy of the data is only valid/verifiable for N period, after which a new copy is required to be considered "valid" (has interesting potential for managing "how to ensure consumers have fresh data/updated data and not being graveyards")
see: https://github.com/StephenOTT/charon-stix/blob/master/src/main/java/io/digitalstate/stix/helpers/ObjectSigning.java and https://github.com/StephenOTT/charon-stix/blob/master/src/main/java/io/digitalstate/charon/camunda/CharonApplication.java#L88-L90 for code snippets of signing
Example of document using Gzip as a compression scheme
Compressed (628 characters)
eyJzaWduZWRfYnkiOiJpZGVudGl0eS0tZDQ0MjgxM2ItN2U3Mi00OWE2LTkzN2EtM2UzNTFlMjE5YTE4IiwiYWxnIjoiSFMyNTYiLCJ6aXAiOiJHWklQIn0.H4sIAAAAAAAAAJWRy27DIBBFfyVibSpj4-c2y6rqpqtWlTXAkFC_IkyiRlH-veA4Sqp00w3MDHcuB-ZE3HGHpCbgHMiW7vyOdiARMeqhSmmiS4FliTSWcUF5mUoqkGkai5xLUXK_gu-VFsFhMEhiVlLGaJK_xazmRZ3GTwXP372oH5XR5reqelBZPIxtEGnoJozIKL5QuqYH25ph01jUE6k_yJJThdoMxpnRw2aZLlihgaYIHrbKlYeFiuZFmmilgGnNyGdENhaGfQf2ahoMT2TCzl802tl--QDmgZYwuYVpMLkD8g_6CyfhMhaKa1pWOVKeFJyCYEhFWmSVyLRCBHL2VgP0YSLT2OPqNo_WdF0jt2CGZreFCS-Ud9WlbR2SGTSortU5YeQc_bMlmYm-mwCz3k9u7J_x6A9fjis5p6sDdHskV82r26K9CJs2KNMqrc4_CH_jFWYCAAA.s6iOIpnwpzkGGdtkSBp-ovFltbb_fCBCPb-zhVhdb8k
Uncompressed (967 chars):
eyJzaWduZWRfYnkiOiJpZGVudGl0eS0tZDQ0MjgxM2ItN2U3Mi00OWE2LTkzN2EtM2UzNTFlMjE5YTE4IiwiYWxnIjoiSFMyNTYifQ.eyJ0eXBlIjoiYXR0YWNrLXBhdHRlcm4iLCJpZCI6ImF0dGFjay1wYXR0ZXJuLS0wODMwNDhiOS00NDRiLTQ2NTMtYmEyNi1iOWMzZDk5ZmNjZjYiLCJjcmVhdGVkIjoiMjAxOC0xMS0yNlQwMTo0ODo0Ny43OTRaIiwibW9kaWZpZWQiOiIyMDE4LTExLTI5VDAxOjQ4OjQ3Ljc5NFoiLCJyZXZva2VkIjpmYWxzZSwib2JqZWN0X21hcmtpbmdfcmVmcyI6WyJtYXJraW5nLWRlZmluaXRpb24tLWJkNWNjY2IwLTcyYTEtNDI5Ny1iODA0LTc0Y2IyZWI3YjViMiJdLCJncmFudWxhcl9tYXJraW5ncyI6W3sic2VsZWN0b3JzIjpbInBhdHRlcm4xIiwicGF0dGVybjIiLCJwYXR0ZXJuMyJdLCJtYXJraW5nX3JlZiI6Im1hcmtpbmctZGVmaW5pdGlvbi0tN2U1ZjEwNzEtZGRiNi00ZWUyLWFlYmYtMmQ1ZTk4NjAxNWEwIn1dLCJuYW1lIjoic29tZSBwYXR0ZXJuIiwia2lsbF9jaGFpbl9waGFzZXMiOlt7ImtpbGxfY2hhaW5fbmFtZSI6IkNoYWluMSIsInBoYXNlX25hbWUiOiJwaGFzZTEifSx7ImtpbGxfY2hhaW5fbmFtZSI6IkNoYWluMSIsInBoYXNlX25hbWUiOiJwaGFzZTIifV0sInhfc29tZUN1c3RvbUtleSI6Ik15IGN1c3RvbSB2YWx1ZSIsInhfc29tZU90aGVyQ3VzdG9tX2tleSI6MzkzOX0.x80xmZyqNMnoMxkrdc6ew45KzG0ro45_6ahlEcBHiyY
difference: 64%
Concept: Use of the encoded sring (base64) increases the string size, but we have a "copy and pasteable" string that will decode into the proper format, thus helping to guarantee that the consumer can always recreate the canon structure. If long term validity is required, then the encoded string can be stored until such time as the JSON signing spec has been completed and adopted. migration from the encoded string to a future json signing spec would be to resign as valid or have the original source re-issue the CTI with new signatures.
If the upstream system cannot provide refreshes of existing data, then we need to ask what is the requirement for downstream continual validation of the data. Are we validating that the data did not change or are we validating that the data came from the said source. I initial thoughts are that the actual concern would be about validating that the data did not change, in which case, we should be discussing a different solution such as continual object aggregation hash signing or block-chain style solutions.