I apologize in advance for the length of this post. I donβt know enough about this problem to correctly determine what a specific problem really is! But, in any case, we made calls against our Membership API to request information about our members (affiliation dates, membership types, etc.), Using the steps and recommendations provided by @Leigh here and they work great! Thanks again, Lee, our members are very happy that we were able to do this!
Now I want to configure single sign-on for our members, allowing them to log in to our page, and then go to their member profile already registered on this site. According to the API documentation , I need to do the following:
"Use your signature certificate to sign the portal username for logging in."
I am completely stuck on this. I have been given a private XML key (generated by their .NET application) in the form
<RSAKeyValue><Modulus>{stuff}</Modulus><Exponent>{stuff}</Exponent><P>... etc etc
I understand that I cannot work with this format directly and must convert it to PEM or similar. Using OpenSSL, I think I did it, and now I have a file in the format "----- START A PRIVATE KEY ----- {stuff} ----- END PRIVATE KEY -----."
Using the Leigh solution gives me a signature, but this does not match the example provided in the API docs. I think this is due to the fact that he uses HmacSHA1, while they note that βthe signature in the header uses HMAC SHA1, while the signature for creating security tokens uses the public / private key pair and RSA-SHA1. The same method cannot be used to generate both. " I tried to change
<cfset key = key.init(jKey,"HmacSHA1") />
to
<cfset key = key.init(jKey,"RSA-SHA1") />
and got the "RSA-SHA1 algorithm is unavailable."
I tried copying and pasting some other suggested solutions, but none of them work. One example (obtained from 12Robots.com ):
<cfset cipher = createObject('java', 'javax.crypto.Cipher').getInstance("RSA") /> <cfset encMode = cipher.ENCRYPT_MODE /> <cfset encryptedValue = "" /> <cfset cipher.init(encMode, key) /> <cfset stringBytes = stringToSign.getBytes("UTF8") /> <cfset encryptedValue = cipher.doFinal(stringBytes, 0, len(inputString)) /> <cfdump var="#encryptedValue#">
The "key" in this case is the PEM text that I mentioned earlier, and "stringToSign" is the username. The error I get is: "Either there are no methods with the specified method name and argument types, or the init method is overloaded with argument types that ColdFusion cannot decrypt reliably. ColdFusion detected 0 methods that match the arguments provided. If it is a Java object and you confirmed, that the method exists, use the javacast function to reduce ambiguity. "
One more thing I tried:
<cfset rsaPrivateKey = toBase64(key, "utf-8")> <cfset jKey = JavaCast("string", rsaPrivateKey)> <cfset jMsg = JavaCast("string", stringToSign).getBytes("ASCII")> <cfset key = createObject("java", "java.security.PrivateKey")> <cfset keySpec = createObject("java", "java.security.spec.PKCS8EncodedKeySpec")> <cfset keyFactory = createObject("java", "java.security.KeyFactory")> <cfset b64dec = createObject("java", "sun.misc.BASE64Decoder")> <cfset sig = createObject("java", "java.security.Signature")> <cfset byteClass = createObject("java", "java.lang.Class")> <cfset byteArray = createObject("java", "java.lang.reflect.Array")> <cfset byteClass = byteClass.forName(JavaCast("string", "java.lang.Byte"))> <cfset keyBytes = byteArray.newInstance(byteClass, JavaCast("int", "1024"))> <cfset keyBytes = b64dec.decodeBuffer(jKey)> <cfset sig = sig.getInstance("SHA1withRSA", "SunJSSE")> <cfset sig.initSign(keyFactory.getInstance("RSA").generatePrivate(keySpec.init(keyBytes)))> <cfset sig.update(jMsg)> <cfset signBytes = sig.sign()> <cfset finalSig = ToBase64(signBytes)> <cfdump var="#finalSig#">
Which gives me "java.security.InvalidKeyException: invalid key format." BTW, if I set rsaPrivateKey to "key", I get another error, "java.security.InvalidKeyException: IOException: DerInputStream.getLength (): lengthTag = 127, too big." I'm glad I get different error messages; at least something happens !:-)
Again, I don't know what these Java functions do. And of course, I donβt understand why something similar in a straightforward way turned out to be so complicated! But my suspicion is that I either incorrectly stored the PEM secret key or incorrectly read from the database (or both), and this is what contributes to the failure of these various solutions. But I do not know, suffice it to say if this is so.
I would welcome any insights or suggestions that could help me! If anyone needs more information, I will be happy to provide this. Thank you all in advance!