Есть внешний сервис у которого я должен дергать ручки, сервис находится за прокси с аутентификацией по сертификату. Можно ли подписать запрос сертификатом напрямую в APEX без импортирования сертификатов в SF из JKS?
Есть внешний сервис у которого я должен дергать ручки, сервис находится за прокси с аутентификацией по сертификату. Можно ли подписать запрос сертификатом напрямую в APEX без импортирования сертификатов в SF из JKS?
Интересная тема! Активно работаю со всякими интеграциями, но никогда не сталкивался с таким. Тоже с удовольствием послушаю про решение.
С ходу нагугл вот такое
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_callouts_client_certs_http.htm
Но не уверен что это твой случай.
Я так понимаю что под "без импортирования сертификатов в SF из JKS" ты имеешь в виду то что говорится в доке по ссылке в пункте "1. Generate a certificate. Note the Unique Name of the certificate."?
Если получится сделать, не кидай тему, напиши здесь про решение!
Интересная тема! Активно работаю со всякими интеграциями, но никогда не сталкивался с таким. Тоже с удовольствием послушаю про решение. С ходу нагугл вот такое https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_callouts_client_certs_http.htm Но не уверен что это твой случай. Я так понимаю что под [i]"без импортирования сертификатов в SF из JKS"[/i] ты имеешь в виду то что говорится в доке по ссылке в пункте "1. Generate a certificate. Note the Unique Name of the certificate."? Если получится сделать, не кидай тему, напиши здесь про решение!
Да, вся суть в том, чтобы использовать req.setClientCertificateName('DocSampleCert'); нужно имортировать JKS, а для его создания надо приватный ключ, а его по понятным причинам раздавать налево и направо никто не будет.
Да, вся суть в том, чтобы использовать req.setClientCertificateName('DocSampleCert'); нужно имортировать JKS, а для его создания надо приватный ключ, а его по понятным причинам раздавать налево и направо никто не будет.
А попросить чтобы на том прокси дали возможность авторизироваться через Basic или Token авторизацию и добавлять их в хедер?
А попросить чтобы на том прокси дали возможность авторизироваться через Basic или Token авторизацию и добавлять их в хедер?
А там Basic тоже есть ) Это требования безопасников, так как у SF большой рендж IP с которых он может стучаться (https://help.salesforce.com/articleView?id=000321501&type=1&mode=1), то вместо добавления этих адресов в iptables, они просто ставят прокси, который принимает запросы только от подсетей SF.
А может у SF есть возможность слать запросы с одного IP, никто не сталкивался?
А там Basic тоже есть ) Это требования безопасников, так как у SF большой рендж IP с которых он может стучаться (https://help.salesforce.com/articleView?id=000321501&type=1&mode=1), то вместо добавления этих адресов в iptables, они просто ставят прокси, который принимает запросы только от подсетей SF. А может у SF есть возможность слать запросы с одного IP, никто не сталкивался?
Нет, нету. Я когда-то давно тоже пробовал нагуглить как не прописывать весь диапазон IP адресов. Не нашел.
Нет, нету. Я когда-то давно тоже пробовал нагуглить как не прописывать весь диапазон IP адресов. Не нашел.
В итоге выпустили нам отдельный сертификат. Letsencrypt не стали, чтобы каждые 3 месяца не проделывать следующие шаги, к которым пришел через боль и страдания Поэтому сделал себе заметку, которой делюсь.
Итак имеем PEM сертификат mycert.crt и приватный ключ myserver.key,
а также установленные openssl и java keytool.
Необходимо сделать 3 шага:
1. Подготовить в виде PEM полную цепочку сертификатов.
2. Конвертировать эту цепочку из PEM в PKCS12.
3. Конвертировать цепочку из PKCS12 в JKS.
1.
Для начала проверим что ключ от нашего сертификата:
openssl x509 -noout -modulus -in mycert.crt | openssl md5
openssl rsa -noout -modulus -in myserver.key | openssl md5
Конечный JKS должен содержать в себе всю цепочку сертификатов до корневого(они обычно в общем доступе),
корневой должен быть одним из этого списка:
https://cs32.salesforce.com/cacerts.jsp
команда для проверки что наш серт из этой цепочки:
openssl verify -verbose -CAfile Root.crt -untrusted Intermediate.crt ssl_certificate.crt
но этого недостаточно, поэтому проверяем еще так:
openssl x509 -noout -in mycert.crt -text | grep -A1 'Authority Key Identifier'
openssl x509 -noout -in Intermediate.crt -text | grep -A1 'Subject Key Identifier'
Связываем промежуточные и корневой сертификаты от дочернего к родительскому:
cat intermediate1.crt intermediate2.crt rootca.crt > cabundle.crt
2.
Делаем PKCS12:
openssl pkcs12 -export -chain -inkey myserver.key -in mycert.crt -name "MySuperCert" -caname "Intermediate_1" -caname "Intermediate_2" -caname "Root_CA" -CAfile cabundle.crt -out mychain.p12
Обратите внимание на ключ "-chain". Без него это будет просто разрозненная пачка каких-то сертификатов в контейнере. А нам нужно, чтобы имела место быть явная связь между ними.
3.
PKCS12 в JKS:
./keytool -importkeystore -destkeypass secret -deststorepass secret -destkeystore container.jks -srckeystore mychain.p12 -srcstoretype PKCS12 -srcstorepass secret -alias "MySuperCert"
-deststorepass - пароль от JKS контейнера, Salesforce требует длину от 6 до 8 символов
-alias - допустимы цифры буквы и подчеркивания(кроме двойных, конечных и начальных)
Теперь можно загрузить JKS в Salesforce и делать красиво:
request.setClientCertificateName('MySuperCert');
Cертификат не загружается в SF?
Если у вас стоит последний DataLoader, то скорее всего выполнив команду:
java -version
То тут есть засада, Salesforce принимает JKS сделанный только в java 8 ¯\_(ツ)_/¯
Ищем подходящий keytool и повторяем последний шаг.
sudo find / -name keytool
В итоге выпустили нам отдельный сертификат. Letsencrypt не стали, чтобы каждые 3 месяца не проделывать следующие шаги, к которым пришел через боль и страдания ;) Поэтому сделал себе заметку, которой делюсь. Итак имеем PEM сертификат mycert.crt и приватный ключ myserver.key, а также установленные openssl и java keytool. Необходимо сделать 3 шага: 1. Подготовить в виде PEM полную цепочку сертификатов. 2. Конвертировать эту цепочку из PEM в PKCS12. 3. Конвертировать цепочку из PKCS12 в JKS. 1. Для начала проверим что ключ от нашего сертификата: [code] openssl x509 -noout -modulus -in mycert.crt | openssl md5 openssl rsa -noout -modulus -in myserver.key | openssl md5 [/code] хеши должны совпадать. Конечный JKS должен содержать в себе всю цепочку сертификатов до корневого(они обычно в общем доступе), корневой должен быть одним из этого списка: https://cs32.salesforce.com/cacerts.jsp команда для проверки что наш серт из этой цепочки: [code] openssl verify -verbose -CAfile Root.crt -untrusted Intermediate.crt ssl_certificate.crt [/code] но этого недостаточно, поэтому проверяем еще так: [code] openssl x509 -noout -in mycert.crt -text | grep -A1 'Authority Key Identifier' openssl x509 -noout -in Intermediate.crt -text | grep -A1 'Subject Key Identifier' [/code] и так идем до корневого где для каждого сертификата его 'Authority Key Identifier' должен быть равен 'Subject Key Identifier' сертификата, которым он подписан. Связываем промежуточные и корневой сертификаты от дочернего к родительскому: [code] cat intermediate1.crt intermediate2.crt rootca.crt > cabundle.crt [/code] 2. Делаем PKCS12: [code] openssl pkcs12 -export -chain -inkey myserver.key -in mycert.crt -name "MySuperCert" -caname "Intermediate_1" -caname "Intermediate_2" -caname "Root_CA" -CAfile cabundle.crt -out mychain.p12 [/code] Обратите внимание на ключ "-chain". Без него это будет просто разрозненная пачка каких-то сертификатов в контейнере. А нам нужно, чтобы имела место быть явная связь между ними. 3. PKCS12 в JKS: [code] ./keytool -importkeystore -destkeypass secret -deststorepass secret -destkeystore container.jks -srckeystore mychain.p12 -srcstoretype PKCS12 -srcstorepass secret -alias "MySuperCert" [/code] -deststorepass - пароль от JKS контейнера, Salesforce требует длину от 6 до 8 символов -alias - допустимы цифры буквы и подчеркивания(кроме двойных, конечных и начальных) Теперь можно загрузить JKS в Salesforce и делать красиво: [code] request.setClientCertificateName('MySuperCert'); [/code] Cертификат не загружается в SF? Если у вас стоит последний DataLoader, то скорее всего выполнив команду: [code] java -version [/code] вы увидите следующее: openjdk version "12" 2019-03-19 OpenJDK Runtime Environment Zulu12.1+3-CA (build 12+33) OpenJDK 64-Bit Server VM Zulu12.1+3-CA (build 12+33, mixed mode, sharing) То тут есть засада, Salesforce принимает JKS сделанный только в java 8 ¯\_(ツ)_/¯ Ищем подходящий keytool и повторяем последний шаг. [code] sudo find / -name keytool [/code] я нашел у себя ./jdk1.8.0_201.jdk/Contents/Home/jre/bin/keytool и сним все заработало
Низкий поклон за столь подробное описание решения!
Низкий поклон за столь подробное описание решения! [img]http://memesmix.net/media/created/jhntve.jpg[/img]
о, хорошую тему подняли
у меня безопасники настаивают на использовании нашего само-подписанного сертификата
они прочитали сэйлсфорс хелп и тыкают в эту статью
https://help.salesforce.com/articleView?language=en_US&type=1&mode=1&id=000326722
When using mutual authentication/2-way SSL, Salesforce.com can present a self-signed certificate to the target host (that must present a CA signed certificate to Salesforce)
flow который они требуют такой:
сэйлсфорс шлет наш self signed сертификат и сервер ответит с CA-signed сертификатом
Я не могу им доказать что это невозможно. Я так понял сэйлсфорс acting as a client нельзя заставить выслать не CA-Signed сертифкат, ни при помощи mTls, ни при помощи обычного сертификата. И self-signed на который они ссылаются в доке выше сэйлсфорс имеет ввиду только Salesforce-self-signed а не 3rd party, но к сожалению это прямо не указано.
Сертификат я сделал правильно, при загрузке сэйлсфорс видит что подписан моей конторой (self signed)в опциях это видно, но! тип всё равно ставится CA-Signed. И при попытке использовать летит эксепшен
System.CalloutException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
я так понимаю это потому что чейн обрывается (self signed) и нет пути до CA-root, что логично.
Единственный вариант когда при загрузке сертификата сэйлсфорс корректно ставит тип "self-signed" это когда сертификат self-signed самим сэйлсфорсом.
Пробовали использовать mTLS, тут еще немного труднее. Я так понял эта настройка только для связи С сэйлсфорсом, и сэйлсфорс когда выступает как клиент не шлет сертификат.
Если у кого есть информация на тему буду рад выслушать.
о, хорошую тему подняли у меня безопасники настаивают на использовании нашего само-подписанного сертификата они прочитали сэйлсфорс хелп и тыкают в эту статью https://help.salesforce.com/articleView?language=en_US&type=1&mode=1&id=000326722 When using mutual authentication/2-way SSL, Salesforce.com can present a self-signed certificate to the target host (that must present a CA signed certificate to Salesforce) flow который они требуют такой: сэйлсфорс шлет наш self signed сертификат и сервер ответит с CA-signed сертификатом Я не могу им доказать что это невозможно. Я так понял сэйлсфорс acting as a client нельзя заставить выслать не CA-Signed сертифкат, ни при помощи mTls, ни при помощи обычного сертификата. И self-signed на который они ссылаются в доке выше сэйлсфорс имеет ввиду только Salesforce-self-signed а не 3rd party, но к сожалению это прямо не указано. Сертификат я сделал правильно, при загрузке сэйлсфорс видит что подписан моей конторой (self signed)в опциях это видно, но! тип всё равно ставится CA-Signed. И при попытке использовать летит эксепшен System.CalloutException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target я так понимаю это потому что чейн обрывается (self signed) и нет пути до CA-root, что логично. Единственный вариант когда при загрузке сертификата сэйлсфорс корректно ставит тип "self-signed" это когда сертификат self-signed самим сэйлсфорсом. Пробовали использовать mTLS, тут еще немного труднее. Я так понял эта настройка только для связи С сэйлсфорсом, и сэйлсфорс когда выступает как клиент не шлет сертификат. Если у кого есть информация на тему буду рад выслушать.