Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

I need to encrypt (or at least digitally sign) a package of content that is sent from the SharePoint Online server, down to the browser, and then cross-site post (JSONP) the ecrypted content to another system that can decrypt (or validate the signature). My problem is that I haven't come up with a secure way to encrypt the contents when working within the confines of a sandboxed solution and SharePoint Online.

I actually don't need encryption, per-se. I just need to sign the package in such a way that this external system knows I signed it. So, when I mention "encryption" or "encryption key", I am also talking about signature keys (certs, I suppose).

I can think of a few ways to store the encryption key, but I'm not sure any of them are secure:

  1. Store the encryption key in the code. This is typically a no-no, but regular users should not have access to the code. Maybe with obfuscation and/or a different key per-client this would be an option.
  2. Store the encryption key in the content database. This allows the key to be configurable, but my code needs to access the key under the context of any user and since we cannot impersonate or elevate permissions in a sandboxed environment, anyone will be able to make a web service call to get this key if they know what they are doing.
  3. Use the Secure Store Service to store the key. I don't think the SSS is really meant for this since the key would be the same for every user.
  4. Somehow read in the machine key. Even if we can do this in a sandboxed environment, we probably won't know how to unencrypt this on the other end.

Any ideas? I can even do a combination of options if that helps.


Additional Details:

The original verison of this was a Farm Solution that would not work in SharePoint Online. It created a custom ticket and stored the ticket and current user details in a hidden list. It elevated permissions in order to create the entry in the list (regular users could not directly add data to the list). The ticket was returned to the browser and cross-posted to another system anonymously. The other system would make a server-to-server web service call to redeem the ticket to get back the user information and finally provide a session to the user based on the user name found in the redeemed ticket data. The whole purpose is to provide SSO to allow the IFrames to work in our web part. This is only needed if the customer does not already have their own SSO and we only make the calls in the case where authentication is needed.

In SharePoint Online I cannot elevate permissions so spoofing is a concern. I was hoping to simplify the entire design by removing the step where the ticket is redeemed, thus removing the need to temporarily store user information in a custom list and removing the complexity of calling a custom web service. To do this I just need to encrypt/sign the user information so the other system trusts who it is. The problem, as I outlined further above, is preventing others from encrypting/signing their own packet with a different username.

Using another system like Azure would involve authenticating to it and having SSO or using the Secure Store Service (SSS) to authenticate. That may have to be our answer - that every user has to setup their username/password in SSS for SSO to work. Not the answer I was looking for as our non-sandboxed implementation does not require every user to do this and it also allows for an option where users can be generated automatically in the other system.


Update #2:

Even though I was concerned that I could not decrypt something encrypted with the machine key, I thought I would explore this further...

I found that there is a way in .NET to encrypt content based on the MachineKey, but that is based on a MachineKey class that is only available in .NET Framework v4. It is not available in SharePoint code directly. Yes, we could put code that does it in another web app, but that defeats the purpose and would not be allowed in SharePoint Online anyways.

I tried the reflection hack for MachineKey which can work in a farm solution, but does not work in a sandboxed solution (ConfigurationManager.GetSection() fails). Other methods like DPAPI require COM which is not allowed in sandboxed solutions (I haven't tested this, but have read it).

share|improve this question
    
If you would use SSS, could you combine the key stored there with some user specific information, such as O365 username, and use that? IF users don't have access to SSS key that might work as symmetric signature/encryption. –  Jussi Palo Jan 23 '12 at 20:20
    
@JussiPalo, what I didn't make clear is that this other system will take the encrypted packet without there being authentication to it and use the information in the packet to authenticate the user. So, the other system doesn't have any other key piece of data to go on :(. –  Kirk Liemohn Jan 23 '12 at 21:58

1 Answer 1

The secure store service does allow a group of users to map to a single stored credential, so in an on-premise environment it could be a good way to accomplish the secure key storage, but that isn't going to help you from a Sandbox Solution in SharePoint Online :)

The part I am missing here is how the sandbox solution hooks up with the client code you are going to use in the browser to make the call using JSONP? Are you going to use the Client Object Model to access content stored in a list? Is a sandbox web part embedding some signed or encrypted data in the HTML page that JavaScript will use to cross-post?

It seems to me that you need a custom proxy. Use JSONP to submit over SSL to service that signs and encrypts the data and then either returns it to send to the other service, or even sends it directly (i.e. wraps the other service call). I would be looking to combine SharePoint online and Azure or another provider to host a custom service.

share|improve this answer
    
@ChrissBeckett, we do have the client make the JSONP call to the other system (not SP Online). SharePoint provides the packet of data that is posted via the JSONP call. There is no data in a list and no Client Object Model code - we are just providing information about the current user so this other system can impersonate him/her. Yes, it is a sandboxed web part providing signed/encrypted data to the page that JS will cross-post. I'll try to add more details in my original question to see if that helps. –  Kirk Liemohn Jan 23 '12 at 22:10
1  
Why does the encryption have to be done by the sandbox web part? I believe my recommendation still stands. There are simply things you are not going to be able to do in a Sandbox solution. The integration architecture choices you have to move the processing off into a custom web worker or service (in the Cloud somewhere) and then integrate with BCS, have it poll into SharePoint online using web services, or cross-post to it with Silverlight or JSONP. I think you need to move the data encryption routines off SharePoint online. –  Chris Beckett Jan 23 '12 at 22:34
    
You may be on to something, but I just don't see it yet. Currently SharePoint is the only one with the knowledge of who is authenticated to it. If I call out to some other web service and provide that data anonymously, then anyone else can do that and impersonate another user. If I have to authenticate to another system (e.g., Azure), that seems to defeat the whole purpose of what I'm trying to solve (not requiring the user to sign into another system - if they already have SSO then there is no need for this approach). –  Kirk Liemohn Jan 24 '12 at 14:28
2  
Use BCS to create an external list bound to an Azure WCF service, then write the data to encrypt into the list with the Client OM. The Azure service picks up the change, encrypts and submits externally. In this example, you are using BCS like a queue for external processing. It may not seem elegant, but integrating cloud solutions is going to require some new patterns to fit what is available to us. –  Chris Beckett Jan 25 '12 at 9:28
    
That just might work assuming that when john.doe is signed into SharePoint, SP can call the BCS/Azure service on his behalf, but john.doe cannot call the BCS/Azure service directly. I think that can be the case, but curious if you agree. I agree that cloud solutions require a new way of thinking. I don't think the budget can handle this approach right now, but I will keep it as a potential option. –  Kirk Liemohn Jan 25 '12 at 15:32

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.