I think the proper solution would be for the VRML browser developers to incorporate a public key cryptographic system (or something similar) right into their software, as well as provide the matching encryption tool for VRML authors. PGP is an open source system that should work for this purpose, and any existing tool for encryption with PGP could be used on the content files, provided that a public encryption key is provided along with the browser.

One problem with this is that every browser developer will likely provide his own public encryption key, and so only his browser would be able to decrypt and display a world file that has been encrypted using that key. (Bad news, in my opinion.)

Alternatively, one could use a single public encryption key and multiple private decryption keys, and only issue a private decryption key to a trusted developer of a VRML browser. Or perhaps a standardized vrmldecrypt.dll library could be made available to browser vendors so that they never actually see the decryption algorithm nor private decryption key. To get around the problem of someone getting a pirate copy of the dll and writing their own cracking software, the dll might have to contain some sort of activation/expiration system that allows legitimate browser developers to keep the dll operating, but make the dll of limited/temporary use to the pirate. The standardization agency that provides the dll would then have to issue renewal codes to the legitimate browser developers, and to users running recognized software. This is essentially a periodic security update that each user's VRML browser would have to download automatically using some sort of secure download protocol (i.e. like the updates of your virus scanner).

There is a decent discussion of public-key cryptography and digital signatures on Wikipedia at http://en.wikipedia.org/wiki/Public_key_cryptography.

I would not be surprized to hear that the Web3D Consortium has some sort of encryption system in its X3D specification (or, at least, that such a system is in development).

As a temporary measure, consider the following proposal. A VRML Proto could be created (using javascript) that can be used in a very basic wrl file to load the actual full wrl using a javascript call, thus preventing the world from appearing in a browser cache.
If the final world is actually served up from a server side PHP script then the proto could also do an initial message exchange with the PHP script to first tell the server which browser is being used to load the world. Then, the server would send the final wrl to the user's system only if that browser is in a list of recognized browsers.
In this way one could, for instance, make it difficult for someone to use VRMLpad to download the final wrl.

I'm sure there's a way for a crafty scripter to modify a copy of the loader proto and get the final VRML world from the PHP script, but the point of this temporary/interim measure is to make it more difficult to pirate VRML content, not to completely prevent it.

The exchange between client and server might go something like this:
  1. The user loads the startup wrl file.
  2. The loader proto tries to load either the final wrl file or from a web link that is a server php script (Both possibilities are made available so that the VRML author can have a choice, since some authors may not have access to a web server that supports running PHP scripts). The PHP script is called using a web link that will have a parameter string appended to it (eg. the ID string for the VRML browser).
  3. The server replies by sending the wrl data for the final world, or (in the case of the PHP script) it only sends the wrl data if the supplied browser ID string is recognized.
The PHP script could also be written so that it can serve up more than one VRML world, depending on a second parameter in the URL formed by the loader proto.

Below is an example of the kind of script that the loader might use to "talk" with the PHP script on the user's web server.

http://www.myserver.net/Proto_Loader.wrl
#VRML V2.0 utf8

PROTO Loader [
    field SFString server "http://www.myserver.net/fetchwrl.php"
    field SFString worldname "My%20World"
    field SFBool isPHP TRUE
]{
    DEF TS TimeSensor {
        cycleInterval 1
        stopTime -1
        startTime 0
        loop TRUE
        enabled TRUE
    }
    DEF SC Script {
        directOutput TRUE
        mustEvaluate TRUE
        field SFString server IS server
        field SFString worldname IS worldname
        field SFBool isPHP IS isPHP
        eventIn SFTime starttime
        field SFNode TS USE TS
        field SFString browsername ""
        field SFString newurl ""
        field SFString parameter ""
        url "vrmlscript:
            function starttime() {
                TS.enabled = false;
                if (isPHP) { // The user has supplied a url to a php script.
                    browsername = Browser.getName();
                    newurl = server + '?name=' + browsername + '&world=' + worldname;
                } else { // The user has supplied a url to a wrl file, not a php script.
                    newurl = server;
                }
                Browser.loadURL(newurl, parameter);
            }
        "
    }
    ROUTE TS.cycleTime TO SC.starttime
}

The user then just creates a startup world that just contains the following:

http://www.myserver.net/startup.wrl
#VRML V2.0 utf8

EXTERNPROTO Loader [
    field SFString server
    field SFString worldname
    field SFBool isPHP
]["http://www.myserver.net/Proto_Loader.wrl"]

Loader {
    url "http://www.myserver.net/fetchwrl.php"
    worldname "Pointworlds" # This tells the PHP script what VRML to send.
    isPHP TRUE
}

The PHP script that is on the web server then has the job of comparing the supplied "worldname" string to its list of available worlds. It must also compare the "browsername" string that it receives (see the construction of newurl in the proto definition) to its list of trusted VRML browsers. When it finds a match in both lists (i.e. trustedbrowserslist and availableworldslist) then it can proceed to send the contents of the appropriate wrl file (in a non-public directory on the same web server) to the user's browser.

http://www.myserver.net/fetchwrl.php

// I have not written the code for this PHP script. Too busy at the
// moment.  Perhaps someone else might attempt to write it and test it.

As an alternative to http://www.myserver.net/startup.wrl (shown above), a user that does not have access to web services that support PHP scripting can just use the following startup world. (This is not as secure, though I think it still makes it harder to get at the final VRML code.)

http://www.myserver.net/startup2.wrl
#VRML V2.0 utf8

EXTERNPROTO Loader [
    field SFString server
    field SFString worldname
    field SFBool isPHP
]["http://www.myserver.net/loaderProto.wrl"]

Loader {
    server "http://www.pointworlds.com/vrml/home/home.wrl"
    isPHP FALSE
}

Any opinions on this idea?
Am I just talking nonsense?
Any other ideas?